luhara
luhara

Reputation: 25

Python: lxml returns empty list from svg with xpath

I want to access the tspan-tags from the following svg. For that I read that I should use lxml and xpath, normally element.xpath("tspan") should return a list with all tspan-tags, or? But I only get [].

Python code:

from lxml import etree

folder_input = "input"
folder_output = "output"

# generate ready to use vue components
def generate():
    svgFile  = open(folder_input + "/secondfloor.svg", "r")
    element = etree.parse(svgFile)
    print(element)

    tspans = element.xpath("tspan")

    print(tspans)

    for tspan in tspans:
        print(tspan.text)

    print("END")

SVG file:

<svg width="687px" height="1519px" viewBox="0 0 687 1519" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Firstfloor" transform="translate(-229.000000, -29.000000)">
            <g id="firstfloor" transform="translate(233.000000, 33.000000)">
                <g id="rooms">
                    <g id="A1.06" transform="translate(428.000000, 1061.000000)">
                        <polyline id="Shape" stroke="#FFFFFF" stroke-width="7" fill="#FF0000" points="7.09 222.98 251.03 222.98 251.03 0.27 7.09 0.27 7.09 173.16"></polyline>
                        <path d="M7.09,222.98 L7.09,202.66" id="Shape" stroke="#FFFFFF" stroke-width="7"></path>
                        <path d="M0.16,173.91 L14.49,173.91" id="Shape" stroke="#FFFFFF" stroke-width="7"></path>
                        <path d="M0.24,202.66 L14.58,202.66" id="Shape" stroke="#FFFFFF" stroke-width="7"></path>
                        <text id="text" font-family="ArialMT, Arial" font-size="36" font-weight="normal" fill="#FFFFFF">
                            <tspan x="85.4580078" y="61">Line1</tspan>
                            <tspan x="85.4580078" y="102">Line2</tspan>
                            <tspan x="85.4580078" y="143">Line3</tspan>
                            <tspan x="85.4580078" y="184">Line4</tspan>
                        </text>
                    </g>
                    <g id="A1.10" transform="translate(429.000000, 761.000000)">
                        <polyline id="Shape" stroke="#FFFFFF" stroke-width="7" fill="#FF0000" points="14.49 200.07 0.16 200.07 6.93 200.18 7.05 225.48 250.03 225.48 250.03 226.84 250.03 213.43 250.03 0.46 7.05 0.46 7.05 171.07 0.24 171.07 14.58 171.07"></polyline>
                        <text id="text" font-family="ArialMT, Arial" font-size="36" font-weight="normal" fill="#FFFFFF">
                            <tspan x="81.4580078" y="70">Line1</tspan>
                            <tspan x="81.4580078" y="111">Line2</tspan>
                            <tspan x="81.4580078" y="152">Line3</tspan>
                            <tspan x="81.4580078" y="193">Line4</tspan>
                        </text>
                    </g>
                </g>
            </g>
        </g>
    </g>
</svg>

Upvotes: 2

Views: 638

Answers (1)

Josh Voigts
Josh Voigts

Reputation: 4132

You have to add a namespace prefix for svg. Also, your xpath should start with // if you are trying to select from anywhere in the document. As a side note, you should close the file when finished parsing.

from lxml import etree

folder_input = "input"
folder_output = "output"

# generate ready to use vue components
def generate():
    svgFile  = open(folder_input + "/secondfloor.svg", "r")
    element = etree.parse(svgFile)
    svgFile.close()

    print(element)

    ns = {'s': 'http://www.w3.org/2000/svg'}

    tspans = element.xpath("//s:tspan", namespaces=ns)

    print(tspans)

    for tspan in tspans:
        print(tspan.text)

    print("END")

Upvotes: 4

Related Questions