我正在尝试使用Python解析10k行XML文件。该文件的摘录如下所示,描述了一长串元素的一些物理属性。每个元素都由XML文件中的" ble"我已经为每个" ble"编写了Python类。我会遇到的类型。
<header>
<!--SlotModels-->
<slotModels id="SpokeOptimusSlotModels" xml:base="spoke.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
<slotModel id="spokeLEDP">
<var id="g1" type="double"/>
<ble id="DR0005" type="drift">
<d id="l" type="double" unit="mm">240</d>
<d id="r" type="double" unit="mm">20</d>
<d id="ry" type="double" unit="mm">0</d>
</ble>
<ble id="QD0020" model="Quad310" type="quad">
<d id="l" type="double" unit="mm">310</d>
<d id="g" type="double" unit="T/m">g1</d>
<d id="r" type="double" unit="mm">30</d>
</ble>
</slotModel>
<slotModel id="spokeLwu">
<var id="g1" type="double"/>
<ble id="DR0010" type="drift">
<d id="l" type="double" unit="mm">160</d>
<d id="r" type="double" unit="mm">30</d>
<d id="ry" type="double" unit="mm">0</d>
</ble>
<ble id="QD0020" model="Quad310" type="quad">
<d id="l" type="double" unit="mm">310</d>
<d id="g" type="double" unit="T/m">g1</d>
<d id="r" type="double" unit="mm">30</d>
</ble>
</slotModel>
<slotModel id="spokeCryomodule">
<var id="xelmax1" type="double"/>
<var id="rfpdeg1" type="double"/>
<ble id="DR0010" type="drift">
<d id="l" type="double" unit="mm">368.5</d>
<d id="r" type="double" unit="mm">28</d>
<d id="ry" type="double" unit="mm">0</d>
</ble>
<ble id="FM0020" model="spokeCavity" type="fieldMap">
<d id="rfpdeg" type="double" unit="deg">rfpdeg1</d>
<d id="xelmax" type="double" unit="unit">xelmax1</d>
<d id="radiusmm" type="double" unit="mm">28</d>
<d id="lengthmm" type="double" unit="mm">994</d>
<d id="file" type="string" unit="unit">Spoke_F2F</d>
<d id="scaleFactor" type="double" unit="unit">1.0</d>
</ble>
</slotModel>
</slotModels>
<slotModels id="medBetaSlotModels" xml:base="medBeta.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
<slotModel id="medBetaLwu">
<var id="g1" type="double"/>
<ble id="DR0010" type="drift">
<d id="l" type="double" unit="mm">256.2</d>
<d id="r" type="double" unit="mm">50</d>
<d id="ry" type="double" unit="mm">0</d>
</ble>
<ble id="QD0020" model="Quad410" type="quad">
<d id="l" type="double" unit="mm">410</d>
<d id="g" type="double" unit="T/m">g1</d>
<d id="r" type="double" unit="mm">50</d>
</ble>
</slotModel>
<slotModel id="medBetaCryomodule">
<var id="xelmax1" type="double"/>
<var id="rfpdeg1" type="double"/>
<ble id="DR0010" type="drift">
<d id="l" type="double" unit="mm">414.4</d>
<d id="r" type="double" unit="mm">46.87</d>
<d id="ry" type="double" unit="mm">0</d>
</ble>
<ble id="FM0020" model="medBetaCavity" type="fieldMap">
<d id="rfpdeg" type="double" unit="deg">rfpdeg1</d>
<d id="xelmax" type="double" unit="unit">xelmax1</d>
<d id="radiusmm" type="double" unit="mm">46.87</d>
<d id="lengthmm" type="double" unit="mm">1258.8</d>
<d id="file" type="string" unit="unit">MB_F2F</d>
<d id="scaleFactor" type="double" unit="unit">1.0</d>
</ble>
</slotModel>
</slotModels>
<cellModels id="SpokeOptimusCellModels" xml:base="spoke.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
<cellModel id="spokeLEDPCell">
<var id="g1" type="double"/>
<var id="xelmax1" type="double"/>
<var id="rfpdeg1" type="double"/>
<slot id="slot010" model="spokeLEDP">
<d id="g1" type="double">g1</d>
</slot>
<slot id="slot020" model="spokeCryomodule">
<d id="xelmax1" type="double">xelmax1</d>
<d id="rfpdeg1" type="double">rfpdeg1</d>
</slot>
</cellModel>
<cellModel id="spokeCell">
<var id="g1" type="double"/>
<var id="xelmax1" type="double"/>
<var id="rfpdeg1" type="double"/>
<slot id="slot010" model="spokeLwu">
<d id="g1" type="double">g1</d>
</slot>
<slot id="slot020" model="spokeCryomodule">
<d id="xelmax1" type="double">xelmax1</d>
<d id="rfpdeg1" type="double">rfpdeg1</d>
</slot>
</cellModel>
</cellModels>
<cellModels id="medBetaCellModels" xml:base="medBeta.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
<cellModel id="medBetaCell">
<var id="g1" type="double"/>
<var id="xelmax1" type="double"/>
<var id="rfpdeg1" type="double"/>
<slot id="slot010" model="medBetaLwu">
<d id="g1" type="double">g1</d>
</slot>
<slot id="slot020" model="medBetaCryomodule">
<d id="xelmax1" type="double">xelmax1</d>
<d id="rfpdeg1" type="double">rfpdeg1</d>
</slot>
</cellModel>
</cellModels>
</header>
<linac>
<section id="SPOK" rfHarmonic="1" xml:base="spoke.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
<cell id="cell010" model="spokeLEDPCell">
<d id="g1" type="double">5.23025</d>
<d id="g2" type="double">-4.68975</d>
<d id="xelmax1" type="double">0.868945</d>
<d id="xelmax2" type="double">0.865525</d>
<d id="rfpdeg1" type="double">-6.65943</d>
<d id="rfpdeg2" type="double">4.03247</d>
</cell>
<cell id="cell020" model="spokeCell">
<d id="g1" type="double">4.85226</d>
<d id="g2" type="double">-4.77927</d>
<d id="xelmax1" type="double">0.890626</d>
<d id="xelmax2" type="double">0.891124</d>
<d id="rfpdeg1" type="double">22.0298</d>
<d id="rfpdeg2" type="double">31.6618</d>
</cell>
<cell id="cell030" model="spokeCell">
<d id="g1" type="double">4.46164</d>
<d id="g2" type="double">-4.45154</d>
<d id="xelmax1" type="double">1</d>
<d id="xelmax2" type="double">1</d>
<d id="rfpdeg1" type="double">37.712</d>
<d id="rfpdeg2" type="double">47.397</d>
</cell>
<!--SPOKE-->
<section id="MBL" rfHarmonic="2" xml:base="medBeta.xml" xmlns:xi="http://www.w3.org/2001/XInclude">
<cell id="cell010" model="medBetaCell">
<d id="g1" type="double">3.39121</d>
<d id="g2" type="double">-3.31534</d>
<d id="xelmax1" type="double">0.44729</d>
<d id="xelmax2" type="double">0.4477</d>
<d id="xelmax3" type="double">0.453125</d>
<d id="xelmax4" type="double">0.453307</d>
<d id="rfpdeg1" type="double">55.8358</d>
<d id="rfpdeg2" type="double">61.7858</d>
<d id="rfpdeg3" type="double">66.1437</d>
<d id="rfpdeg4" type="double">72.2867</d>
</cell>
<cell id="cell020" model="medBetaCell">
<d id="g1" type="double">3.60124</d>
<d id="g2" type="double">-3.64339</d>
<d id="xelmax1" type="double">0.512886</d>
<d id="xelmax2" type="double">0.512886</d>
<d id="xelmax3" type="double">0.512886</d>
<d id="xelmax4" type="double">0.512886</d>
<d id="rfpdeg1" type="double">77.201</d>
<d id="rfpdeg2" type="double">84.17</d>
<d id="rfpdeg3" type="double">91.207</d>
<d id="rfpdeg4" type="double">98.296</d>
</cell>
</section>
</linac>
请注意,XML文件的结构是&#34; slot&#34;和&#34;单元格&#34;,它们基本上是具有可辨别模式的ble列表,在标题中定义,而数据保存在&#34; linac&#34;。
我想扫描&#34; linac&#34;,然后将每个单元格扩展为我编写的类的完全实例化对象列表,以表示每个单元格。
为此,我希望能够以返回可以为每个slotModel或cellModel调用的函数的方式解析头。换句话说,我想自动生成如下函数:
def spokeLEDP(g1):
bleList = []
bleList.append(drift(l=240, r=20, ry=0)
bleList.append(quad(l=310, g=g1, r=30)
return bleList
def spokeLEDPcell(g1, xelmax1, rfpdeg1):
myList = []
myList.append(spokeLEDP(g1))
myList.append(spokeCryomodule(xelmax1, rfpdeg1))
return myList
我意识到我需要正确地压扁列表,但我希望你明白这个想法。
我目前可以看到继续从标题中动态生成函数的唯一方法是两个步骤。首先,使用Python创建具有必要功能的文本文件。然后将其导入到工作代码中。
这看起来非常笨重而且笨拙。
有没有办法在一步完成我想要做的事情,而不需要对&#34;单元格进行大量重复解析。和&#34;插槽&#34; XML标题中的元素?
非常感谢您阅读这篇文章,以及您可以提供的任何帮助。
(注意:我无法控制XML文件的结构。)
答案 0 :(得分:1)
您可以使用DOM解析器路径为每个节点类型设置处理程序 - 基本上只访问每个节点,运行自定义代码等等。这是一种非常常见的模式。
有一些针对python的XML对象解决方案,没有一个是“很棒”,某些工作,其他的并不真正有用,但用心良好(或非常有限)。
一个相当模糊但有趣的包https://github.com/scieloorg/porteira 一个雄心勃勃的工作包是http://pyxb.sourceforge.net/,您可以根据模式进行“数据绑定”。这是正确的想法,但像大多数python XML包有一些粗略的边缘。我遇到了名称空间问题(对于大多数python项目而言,这可能是一个例子。如果你使用XSD和所有爵士乐进入超级硬核XML,那就更少了。
另一种解决方案是学习XPath并使用它来查询返回带有属性或字典的对象的结构。有很多方法可以给猫皮肤涂抹 - 希望我能给你一些潜在的解决方案。