[Python] inlezen van XML bestand

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • htca
  • Registratie: November 2001
  • Laatst online: 07-10 10:44
Ik heb een XML bestand dat er zo uitziet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>

<project xmlns="http://www.scia.cz">
   
   <def uri="XML test.xml.def"/>
   
   <container id="{39A7F468-A0D4-4DFF-8E5C-5843E1807D13}" t="EP_DSG_Elements.EP_StructNode.1">
      <table id="FD73A147-C50E-4FEB-BDE2-4AE52C4EB2B5" t="EP_DSG_Elements.EP_StructNode.1" name="Node">
         <h>
            <h0 t="Name"/>
            <h1 t="Coord X"/>
            <h2 t="Coord Y"/>
            <h3 t="Coord Z"/></h>
         <obj id="1" nm="N1">
            <p0 v="N1"/>
            <p1 v="0"/>
            <p2 v="0"/>
            <p3 v="0"/></obj>
         
         <obj id="2" nm="N2">
            <p0 v="N2"/>
            <p1 v="6"/>
            <p2 v="0"/>
            <p3 v="0"/></obj>
         
         <obj id="3" nm="N3">
            <p0 v="N3"/>
            <p1 v="6"/>
            <p2 v="3"/>
            <p3 v="0"/></obj>
         
         <obj id="4" nm="N4">
            <p0 v="N4"/>
            <p1 v="6.0685613651785504"/>
            <p2 v="3.0159865966763899"/>
            <p3 v="0"/></obj>
         
         <obj id="5" nm="N5">
            <p0 v="N5"/>
            <p1 v="0"/>
            <p2 v="4.5"/>
            <p3 v="0"/></obj>
      </table>
   </container>
   
   <container id="{ECB5D684-7357-11D4-9F6C-00104BC3B443}" t="EP_DSG_Elements.EP_Beam.1">
      <table id="CF9EE094-CB08-4721-839B-51EDF10A791D" t="EP_DSG_Elements.EP_Beam.1" name="Member 1D">
         <h>
            <h0 t="Name"/>
            <h1 t="Beg. node"/>
            <h2 t="End node"/>
            <h3 t="Cross-section"/>
            <h4 t="FEM type"/>
            <h5 t="Member system-line at"/>
            <h6 t="ey"/>
            <h7 t="ez"/>
            <h8 t="Table of geometry"/></h>
         <obj id="1" nm="B1">
            <p0 v="B1"/>
            <p1 i="1" n="N1"/>
            <p2 i="2" n="N2"/>
            <p3 i="1" n="CS1 - Rectangle (1150; 1000)"/>
            <p4 v="0" t="standard"/>
            <p5 v="1" t="Centre"/>
            <p6 v="0"/>
            <p7 v="0"/>
            <p8 t="">
            <h>
            <h1 t="Node"/>
            <h2 t="Edge"/>
            </h>
            <row id="0">
            <p1 i="1" n="N1"/>
            <p2 v="0" t="Line"/>
            </row>
            <row id="1">
            <p1 i="2" n="N2"/>
            </row>
            </p8></obj>
         
         <obj id="2" nm="B2">
            <p0 v="B2"/>
            <p1 i="2" n="N2"/>
            <p2 i="3" n="N3"/>
            <p3 i="1" n="CS1 - Rectangle (1150; 1000)"/>
            <p4 v="0" t="standard"/>
            <p5 v="1" t="Centre"/>
            <p6 v="0"/>
            <p7 v="0"/>
            <p8 t="">
            <h>
            <h1 t="Node"/>
            <h2 t="Edge"/>
            </h>
            <row id="0">
            <p1 i="2" n="N2"/>
            <p2 v="0" t="Line"/>
            </row>
            <row id="1">
            <p1 i="3" n="N3"/>
            </row>
            </p8></obj>
         
         <obj id="3" nm="B3">
            <p0 v="B3"/>
            <p1 i="4" n="N4"/>
            <p2 i="5" n="N5"/>
            <p3 i="1" n="CS1 - Rectangle (1150; 1000)"/>
            <p4 v="0" t="standard"/>
            <p5 v="1" t="Centre"/>
            <p6 v="0"/>
            <p7 v="0"/>
            <p8 t="">
            <h>
            <h1 t="Node"/>
            <h2 t="Edge"/>
            </h>
            <row id="0">
            <p1 i="4" n="N4"/>
            <p2 v="0" t="Line"/>
            </row>
            <row id="1">
            <p1 i="5" n="N5"/>
            </row>
            </p8></obj>
      </table>
   </container>
   
   <container id="{2127A9B3-36BD-11D4-B337-00104BC3B531}" t="CrossSection.EP_CrossSection.1">
      <table id="77800844-E1B3-4C73-B4B6-544C2A2975F5" t="CrossSection.EP_CssGeometry.1" name="Cross-sections">
         <h>
            <h0 t="Name"/>
            <h1 t="Catalog ID"/>
            <h2 t="Catalog item"/>
            <h3 t="Parameters"/></h>
         <obj id="1" nm="CS1">
            <p0 v="CS1"/>
            <p1 v="EP_CssLib.EP_ProfLib_Concrete.1"/>
            <p2 v="0"/>
            <p3 t="">
            <h>
            <h0 t="Name"/>
            <h1 t="Material"/>
            <h4 t="Length"/>
            </h>
            <row id="0">
            <p0 v="Material"/>
            <p1 i="315" n="C12/15"/>
            </row>
            <row id="1">
            <p0 v="H"/>
            <p4 v="1.1500000000000001"/>
            </row>
            <row id="2">
            <p0 v="B"/>
            <p4 v="1"/>
            </row>
            </p3></obj>
      </table>
   </container>
</project>


En het lukt me niet om dat goed te parsen. Uiteindelijk wil ik uit verschillende element de v waarde aanpassen. Dus bijvoorbeeld:
project/container[3]/table[0]/obj[2]/row[2]/p4['v']
(ik weet het de XML is niet heel geweldig opgezet, maar is buiten mijn invloed)


als ik een findall('container/table') doe, krijg ik een empty list. Ik kan een geneste loop doen, maar iets zegt me dat dit een stuk efficienter kan:
code:
1
2
3
4
5
6
7
8
for container in root.findall('{http://www.scia.cz}container'):
    for table in container.findall ('{http://www.scia.cz}table'):
        for obj in table.findall('{http://www.scia.cz}obj'):
            if obj.attrib['nm'] == 'CS1':
                for p3 in obj.findall('{http://www.scia.cz}p3'):
                    for row in p3.findall('{http://www.scia.cz}row'):
                        for p4 in row.findall('{http://www.scia.cz}p4'):
                            print(p4.attrib)

[ Voor 6% gewijzigd door htca op 01-12-2017 20:49 ]


Acties:
  • 0 Henk 'm!

  • dominic
  • Registratie: Juli 2000
  • Laatst online: 14-09 14:42

dominic

will code for food

Ik ken geen Python maar iets zegt me dat het met de default namespace van doen heeft.

Wanneer je geen controle hebt over het zetten van de default namespace (Third party XML) zou ik overwegen om de default namespace te verwijderen:

code:
1
xmlstring = re.sub(r'\sxmlns="[^"]+"', '', xmlstring, count=1)


Wanneer je wel controle hebt over de XML zou ik adviseren om de namespace een naam te geven:

code:
1
2
3
4
5
6
<project xmlns:scia="http://www.scia.cz">....</project>

ns = {"scia": "http://www.scia.cz"}
tree = et.fromstring(xml)
for node in tree.xpath('//scia:project', namespaces=ns):
    ..doe iets..


Als het goed is zou het met een van bovenstaande oplossingen mogelijk moeten zijn om normale xpath queries te doen.

[ Voor 8% gewijzigd door dominic op 03-12-2017 21:45 ]

Download my music on SoundCloud