0

I would like to extract the text from each visited node but while traversing and build a list. I only get an empty result. Here is the following attempt using dom.el

(defun extract-text-from-dom (dom-node)
  "Recursively extract text from a DOM-NODE."
  (cond
   ((null dom-node) "")
   ((dom-text dom-node) (dom-text dom-node))
   (t
    (mapconcat
     #'extract-text-from-dom
     (dom-children dom-node)
     " "))))

(let* ((html "<div><p>This is a <b>sample</b> text.</p> <br><h1>Another Text</h1></div>")
       (dom-tree (libxml-parse-html-region 1 (length html) html))
       (text (extract-text-from-dom dom-tree)))
  (message "Extracted Text: %s" text))
2
  • In addition to db48x's answer on the correct usage of libxml-parse-html-region, the reason extract-text-from-dom returns an empty result is because of the (dom-text dom-node) check. This will return a non-nil empty string "" for any parent nodes that do not contain text, thus ending the recursion early. Have you tried using dom-texts from dom.el instead?
    – Basil
    Commented Oct 31, 2023 at 9:30
  • ok, thanks, let me check on that
    – alexander
    Commented Oct 31, 2023 at 13:18

1 Answer 1

2

One thing that I notice is that libxml-parse-html-region doesn’t take a string to parse. Instead it parses a region of the current buffer. Use C-h f to look up help for functions. It will tell you what arguments they take, and the docstring will describe those arguments in detail. Try this instead:

(let ((html "<div><p>This is a <b>sample</b> text.</p> <br><h1>Another Text</h1></div>"))
  (with-temp-buffer
    (insert html)
    (let ((text (extract-text-from-dom (libxml-parse-html-region (point-min) (point-max)))))
      (message "Extracted Text: %s" text))))

Note also that dom nodes can have both text and children, so your extraction function isn’t quite right.

7
  • I instead have this error: *** Eval error *** Wrong number of arguments: libxml-parse-html-region, 0
    – alexander
    Commented Oct 31, 2023 at 7:55
  • Maybe it depends on the Emacs version. What does C-h f say? Always use C-h f.
    – db48x
    Commented Oct 31, 2023 at 8:51
  • 1
    @db48x libxml-parse-html-region took 2 mandatory arguments up to and including Emacs 28.
    – Basil
    Commented Oct 31, 2023 at 9:31
  • @alexander Try replacing (libxml-parse-html-region) with (libxml-parse-html-region (point-min) (point-max)).
    – Basil
    Commented Oct 31, 2023 at 9:31
  • @Basil, I have updated the question at: emacs.stackexchange.com/questions/79337/… can you please have a look?
    – alexander
    Commented Oct 31, 2023 at 15:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.