pythonpython-3.xelementtreexml-namespacesxml-attribute

Python ElementTree Get attribute with namespace


Im trying to access "def" in XML so in this example I would be getting Evolus.Common:PlainTextV2 as output. I cant seem to figure out how to get an attribute with a namespace. If I was trying to just get id it works perfectly

Python

for content_ns in root.findall('p_link:Content', namespaces):
        for g_ns in content_ns.findall('text_link:g', namespaces):
            print(g_ns.get("text_link:def"), namespaces) #Error is here

XML

<p:Page xmlns:p="http://www.evolus.vn/Namespace/Pencil">
    <p:Properties>
        <p:Property name="id">bd560990fbd44d0bb01705695bf3a989</p:Property>
        <p:Property name="name">MainMenu</p:Property>
        <p:Property name="width">1920</p:Property>
        <p:Property name="height">1080</p:Property>
        <p:Property name="pageFileName">page_bd560990fbd44d0bb01705695bf3a989.xml</p:Property>
        <p:Property name="zoom">0.512</p:Property>
    </p:Properties>
    <p:Content>
        <g xmlns="http://www.w3.org/2000/svg" p:type="Shape" p:def="Evolus.Common:PlainTextV2" p:sc="Label" id="dd73b82838fd44f1bd33448ee660c214" transform="matrix(1,0,0,1,986,218.00000000000006)">
            <p:metadata>
                <p:property name="disabled">
                    <![CDATA[false]]>
                </p:property>
                <p:property name="width">
                    <![CDATA[100,0]]>
                </p:property>
                <p:property name="fixedWidth">
                    <![CDATA[false]]>
                </p:property>
                <p:property name="label">
                    <![CDATA[Start]]>
                </p:property>
                <p:property name="textColor">
                    <![CDATA[#000000FF]]>
                </p:property>
                <p:property name="textFont">
                    <![CDATA['Comic Sans MS'|normal|normal|12px|none]]>
                </p:property>
                <p:property name="textAlign">
                    <![CDATA[0,0]]>
                </p:property>
            </p:metadata>
            <rect x="0" y="0" style="fill: none; stroke: none; visibility: hidden; display: none;" p:name="bgRect" id="d811e5cd54ad43049db1320884837985" width="31.5" height="17.578125" />
            <text xml:space="preserve" p:name="text" id="3fb2492e898840c9b199798153a8f9bf" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Comic Sans MS&quot;; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none;">
                <tspan x="0" y="0">Start</tspan>
            </text>
        </g>
        <g xmlns="http://www.w3.org/2000/svg" xmlns:p="http://www.evolus.vn/Namespace/Pencil" p:type="Shape" p:def="Evolus.Common:PlainTextV2" p:sc="Label" id="be9cd784a01948ddbd4859852821cd22" transform="matrix(1,0,0,1,992,344.00000000000006)">
            <p:metadata>
                <p:property name="disabled">
                    <![CDATA[false]]>
                </p:property>
                <p:property name="width">
                    <![CDATA[100,0]]>
                </p:property>
                <p:property name="fixedWidth">
                    <![CDATA[false]]>
                </p:property>
                <p:property name="label">
                    <![CDATA[Options]]>
                </p:property>
                <p:property name="textColor">
                    <![CDATA[#000000FF]]>
                </p:property>
                <p:property name="textFont">
                    <![CDATA['Comic Sans MS'|normal|normal|12px|none]]>
                </p:property>
                <p:property name="textAlign">
                    <![CDATA[0,0]]>
                </p:property>
            </p:metadata>
            <rect x="0" y="0" style="fill: none; stroke: none; visibility: hidden; display: none;" p:name="bgRect" id="ecd5d58611e84d04a2e088b5c80d50db" width="43.40625" height="17.578125" />
            <text xml:space="preserve" p:name="text" id="4bf667e202024c9a8502bfcf2e456ab8" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Comic Sans MS&quot;; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none;">
                <tspan x="0" y="0">Options</tspan>
            </text>
        </g>
        <g xmlns="http://www.w3.org/2000/svg" xmlns:p="http://www.evolus.vn/Namespace/Pencil" p:type="Shape" p:def="Evolus.Common:PlainTextV2" p:sc="Label" id="03b64f56ad784e05b713c5d752485476" transform="matrix(1,0,0,1,990,460.00000000000006)">
            <p:metadata>
                <p:property name="disabled">
                    <![CDATA[false]]>
                </p:property>
                <p:property name="width">
                    <![CDATA[100,0]]>
                </p:property>
                <p:property name="fixedWidth">
                    <![CDATA[false]]>
                </p:property>
                <p:property name="label">
                    <![CDATA[Exit]]>
                </p:property>
                <p:property name="textColor">
                    <![CDATA[#000000FF]]>
                </p:property>
                <p:property name="textFont">
                    <![CDATA['Comic Sans MS'|normal|normal|12px|none]]>
                </p:property>
                <p:property name="textAlign">
                    <![CDATA[0,0]]>
                </p:property>
            </p:metadata>
            <rect x="0" y="0" style="fill: none; stroke: none; visibility: hidden; display: none;" p:name="bgRect" id="acce5bb264114eae98ce3590f368c4d1" width="23.578125" height="17.578125" />
            <text xml:space="preserve" p:name="text" id="a838040e72c34fea8fffeb7b63f916d2" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Comic Sans MS&quot;; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none;">
                <tspan x="0" y="0">Exit</tspan>
            </text>
        </g>
    </p:Content>
</p:Page>

Entire Script

class TextObject:
    def __init__(self, idn, name, x, y, content):
        self.idn     = idn
        self.name    = name
        self.x       = x
        self.y       = y
        self.content = content

namespaces = {'p_link': 'http://www.evolus.vn/Namespace/Pencil',
             'text_link': 'http://www.w3.org/2000/svg'}

def main():

    tree = ET.parse('mainmenu.xml')
    root = tree.getroot()

    CreateTextObject(root)  
    print("suc")
    time.sleep(500);



def CreateTextObject(root):
    for content_ns in root.findall('p_link:Content', namespaces):
        for g_ns in content_ns.findall('text_link:g', namespaces):
            print(g_ns.get("text_link:def"), namespaces)
            #if(g_ns.get("text_link:def"))
            for text_ns in g_ns.findall("text_link:text", namespaces):
                for text_content_ns in text_ns.findall("text_link:tspan", namespaces):
                    matrix_str = g_ns.get("transform").replace("matrix(", "").replace(")", "").split(",")
                    name = "MainMenu" + text_content_ns.text + "TextObject"
                    TextObject_1 = TextObject(g_ns.get("id"), name, int(float(matrix_str[4])), int(float(matrix_str[5])), text_content_ns.text)
                    AddTextObjectToJSON(TextObject_1)


def AddTextObjectToJSON(TextObject):
    print("s")
    with open('base.json') as f:
        data = json.load(f)

    #print(TextObject.y)
    data["Objects"][0]["Text"].append({"RX": TextObject.x, "RY": TextObject.y, "FontSize": 70, "Name" : TextObject.name, "Path" : "assets/font/DanielLinssenM5/m5x7.ttf", "Content" : TextObject.content, "Color" : [14, 17, 19, 255]})

    with open('base.json', 'w') as f:
        json.dump(data, f)


main()

Solution

  • find() and findall() take a namespaces parameter (a prefix -> uri mapping). The get() method for attributes does not.

    To get the value of an attribute that is in a namespace, you need to use the {uri}name syntax:

    g_ns.get("{http://www.evolus.vn/Namespace/Pencil}def")