1

I know there are a few similar questions but none of the solutions seemed to work. I need to parse and XML file using python. I am using Elementree I am trying to print the value X. It is working as long as I am just looking for X-Values within EndPosition but I have to look for within all MoveToType. Is there someway to integrate that in Elementree. Thanks!

XML file:

<MiddleCommand xsi:type="MoveToType" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <CommandID>19828</CommandID>
        <MoveStraight>false</MoveStraight>
        <EndPosition>
            <Point>
                <X>528.65</X>
                <Y>33.8</Y>
                <Z>50.0</Z>
            </Point>
            <XAxis>
                <I>-0.7071067811865475</I>
                <J>-0.7071067811865477</J>
                <K>-0.0</K>
            </XAxis>
            <ZAxis>
                <I>0.0</I>
                <J>0.0</J>
                <K>-1.0</K>
            </ZAxis>
        </EndPosition>
    </MiddleCommand>

Python code:

import xml.etree.ElementTree as ET


#tree = ET.parse("102122.955_prog_14748500480769929136.xml")
tree = ET.parse("Move_to.xml")
root = tree.getroot()


for Point in root.findall("./EndPosition/Point/X"):
    print(Point.text)



for Point in root.findall('.//{MoveToType}/Endposition/Point/X'):
    print(Point.text)
mzjn
  • 48,958
  • 13
  • 128
  • 248
ApflaBua
  • 15
  • 5
  • Is it the case that your real XML file has several `MiddleCommand` elements but only some of them have `xsi:type="MoveToType"` attributes? – mzjn Aug 14 '21 at 09:22
  • Yes exactly I have several e.g MoveToType, MoveThroughType, PoitionTolerance... And all of them have Point, X,Y,Z. But i only want the ones from MoveToType – ApflaBua Aug 14 '21 at 10:14

2 Answers2

2

Here is how you can get the wanted X value for MiddleCommand elements with xsi:type="MoveToType". Note that you need to use the full namespace URI inside curly braces when getting the value of the attribute.

import xml.etree.ElementTree as ET
 
tree = ET.parse("Move_to.xml")  # The real XML, with several MiddleCommand elements
    
for MC in tree.findall(".//MiddleCommand"):
    # Check xsi:type value and if it equals MoveToType, find the X value
    if MC.get("{http://www.w3.org/2001/XMLSchema-instance}type") == 'MoveToType':
        X = MC.find(".//X")
        print(X.text)
mzjn
  • 48,958
  • 13
  • 128
  • 248
  • I copy pasted your Code but unfortunately it didnt work. – ApflaBua Aug 14 '21 at 11:01
  • well it just didnt print anything – ApflaBua Aug 14 '21 at 11:08
  • Then I have probably made some assumption that does not hold with your real XML document. Do you understand the concept of XML namespaces and why the code looks like it does? – mzjn Aug 14 '21 at 11:11
  • I didnt not try it with my real XML document. I tried it with what part i posted (I copied that part from the main XML file to a seperate one for testing). I kinda understand the basics of XML. The XML Code is not generated by me.. So i dont understand everything. – ApflaBua Aug 14 '21 at 11:13
  • I tested my code on an XML document with two `MiddleCommand` under a common root element. What happens if you simply add a root element to the XML in the question (you can call it `root`; the name does not matter)? – mzjn Aug 14 '21 at 11:18
  • The code presupposes a common root element (because that is what you have in the real XML document). `tree.findall(".//MiddleCommand")` searches for descendants. It does not work if XML document only contains a single `MiddleCommand` element. – mzjn Aug 14 '21 at 11:47
  • I would love to. But i dont know how haha – ApflaBua Aug 21 '21 at 13:08
  • Oh yeah that was easy haha. – ApflaBua Aug 21 '21 at 13:20
0

The below will find any X for you.

for x in root.findall(".//X"):
    print(x.text)
balderman
  • 22,927
  • 7
  • 34
  • 52
  • As mention in the comment above, I cant use that findall, because I need to differenciate between different types of "X" – ApflaBua Aug 14 '21 at 10:15