Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse XML using Python and printing the whole element

This is my first question here. Usually I can find what I need, but after a week of searching and trying I am at the same place, so I need your help.

I have a book that is in a large XML file that is over 6000 lines long. What I need to do is to take an element <sec> and put it's content in a string. Sometimes that element has only one paragraph, and sometimes it has more, sometimes paragraph has lists, and other things, and I need to capture that all in a string.

Here is an example how book is formated.

<book>
    <book-body>
        <book-part id="ch01" book-part-type="chapter">
            <book-part-meta>
                <title-group>
                    <label><target target-type="page" id="pg1"/>Chapter 1</label>
                    <title>Some Title</title>
                </title-group>
            </book-part-meta>
            <body>
                <sec id="ch01lev1sec1" disp-level="level1">
                    <title>Introduction</title>
                    <p>This is a <em>paragraph</em></p>
                    <p>This is second paragraph
                        <list list-type="bullet">
                        <list-item><p>List Item 1</p></list-item>
                        <list-item><p>List Item 2</p></list-item>
                        <list-item><p>List Item 3</p></list-item>
                        </list>
                    </p>
                </sec>
            </body>
        </book-part>
    </book-body>
</book>

And from this example I need everything inside the tag (ideally without a title, but I will figure that out later). I have tried using "xml.etree.ElementTree", and using "minidom" but unsuccessfully.

Here is an example of my code using minidom

from xml.dom import minidom

xmldoc = minidom.parse("xCHES.xml")

book = xmldoc.getElementsByTagName("book")[0]

sec = book.getElementsByTagName("sec")

And when I list a number of elements I get the same number as when I search for "<sec" in xml file, so I guess I got them all. After this point I am stuck, I can't find the way how to extract everything as a text.

The same thing is with "ElementTree", I can locate all <sec> elements but I can't extract the text, or just extract the small part of it.

So if anyone can help me with this problem, it would be great. It doesn't matter what method, as long as it finishes the job.

EDIT: Desired output would be

<title>Introduction</title>
<p>This is a <em>paragraph</em></p>
<p>This is second paragraph
    <list list-type="bullet">
    <list-item><p>List Item 1</p></list-item>
    <list-item><p>List Item 2</p></list-item>
    <list-item><p>List Item 3</p></list-item>
    </list>
</p>

But as a sting. This could be in one line, formatting is irrelevant.

Thank you :)

like image 889
GoranR Avatar asked Sep 25 '26 22:09

GoranR


1 Answers

Following @stovfl's answer on How to get inner content as string using minidom from xml.dom?

Perhaps this works for you?

def getText(nodelist):
    # Iterate all Nodes aggregate TEXT_NODE
    rc = []
    for node in nodelist:
        if node.nodeType == node.TEXT_NODE:
            rc.append(node.data)
        else:
            # Recursive
            rc.append(getText(node.childNodes))
    return ''.join(rc)


# Iterate <sec..>...</sec> Node List
for node in nodelist:
    print(getText(node.childNodes))

The output:

                Introduction
                This is a paragraph
                This is second paragraph

                    List Item 1
                    List Item 2
                    List Item 3
like image 143
PythonSherpa Avatar answered Sep 27 '26 13:09

PythonSherpa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!