Python 解析PDML/XML并为其选择特定字段
我正在使用ElementTreeXML API,并试图用Python解析一个大的PDML(XML)文件。我试图获得一个带有特定信息字段的表格数据帧输出。以下是实际文件的子集Python 解析PDML/XML并为其选择特定字段,python,regex,xml,parsing,elementtree,Python,Regex,Xml,Parsing,Elementtree,我正在使用ElementTreeXML API,并试图用Python解析一个大的PDML(XML)文件。我试图获得一个带有特定信息字段的表格数据帧输出。以下是实际文件的子集 <?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="pdml2html.xsl"?> <!-- You can find pdml2html.xsl in C:\Program Files\W
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="pdml2html.xsl"?>
<!-- You can find pdml2html.xsl in C:\Program Files\Wireshark or at https://code.wireshark.org/review/gitweb?p=wireshark.git;a=blob_plain;f=pdml2html.xsl. -->
<pdml version="0" creator="wireshark/3.2.2" time="Sun Mar 22 23:53:43 2020" capture_file="C:\Users\anyoung\AppData\Local\Temp\wireshark_Wi-Fi 2_20200322234518_a20824.pcapng">
<packet>
<proto name="geninfo" pos="0" showname="General information" size="66">
<field name="frame.cap_len" showname="Capture Length: 66 bytes (528 bits)" size="0" pos="0" show="66"/>
<field name="frame.marked" showname="Frame is marked: False" size="0" pos="0" show="0"/>
<field name="frame.cap_len" showname="Capture Length: 66 bytes (528 bits)" size="0" pos="0" show="66"/>
<field name="frame.marked" showname="Frame is marked: False" size="0" pos="0" show="0"/>
<field name="caplen" pos="0" show="66" showname="Captured Length" value="42" size="66"/>
<field name="timestamp" pos="0" show="Mar 22, 2020 23:45:34.045301000 Pacific Daylight Time" showname="Captured Time" value="1584945934.045301000" size="66"/>
</proto>
我真的很难用语法来完成上面的工作。我甚至无法得到任何接近的结果。lxml
lxml将允许您使用XSLT转换XML文档。出于某种原因,XSLT被忽略,取而代之的是暴力编程对象。然而,在处理和转换XML数据时,我更喜欢使用XLST
如果您必须每天处理XML数据,我强烈建议您学习XSLT并定期使用它
XLST转换XML文档:packet.xsl
变量用于分隔符和行尾(EOL),便于修改
标题行和字段的模板用于在必要时重新排列或添加新字段
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" media-type="string" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="delimiter" select="'	'"/>
<xsl:variable name="EOL" select="'
'"/>
<xsl:template match="/pdml/packet/proto">
<xsl:call-template name="header-row"/>
<xsl:apply-templates match="field"/>
</xsl:template>
<xsl:template match="field">
<xsl:value-of select="@name"/>
<xsl:value-of select="$delimiter"/>
<xsl:value-of select="@size"/>
<xsl:value-of select="$delimiter"/>
<xsl:value-of select="@value"/>
<xsl:value-of select="$EOL"/>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template name="header-row">
<xsl:element name="row">
<xsl:text>field</xsl:text>
<xsl:value-of select="$delimiter"/>
<xsl:text>size</xsl:text>
<xsl:value-of select="$delimiter"/>
<xsl:text>value</xsl:text>
<xsl:value-of select="$EOL"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
制表符分隔的输出
field size value
frame.cap_len 0
frame.marked 0
frame.cap_len 0
frame.marked 0
caplen 66 42
timestamp 66 1584945934.045301000
这里是另一个XSLT示例(更多用于@Kristian) XML输入(Input.XML)
XSLT1.0(test.xsl)
Python 3
从lxml导入etree
tree=etree.parse(“input.xml”)
xslt=etree.parse(“test.xsl”)
new_tree=tree.xslt(xslt)
打印(新树)
打印输出
字段大小值
frame.cap_len 0
帧0.0
frame.cap_len 0
帧0.0
卡普兰66 42
时间戳66 1584945934.045301000
我同意XSLT是一个很好的选择,但是在输出文本时,使用xsl:element
创建一组元素会让人感到困惑@DanielHaley,我创建XML元素只是为了允许选择XML或纯文本。这只是一个例子,回答了这个问题,为他指明了正确的方向。有很多方法可以剥猫皮……不幸的是,lxml似乎无法使用XSTL生成输出。我本来想做你做的事;然而,lxml etree.parse似乎只有在生成XML文档时才起作用。如果能看到lxml正确地使用XSLT,那就太好了。太好了!也许我应该发布一个问题,询问为什么我的示例不能与您的XSLT一起使用谢谢您@Daniel Haley,我从我两年前编写的命令行工具中获取了一段代码。该工具需要足够灵活,以生成XML或纯文本(带或不带XLST文档)。我应该和你的2号班轮一起去。干杯
./test.py
field size value
frame.cap_len 0
frame.marked 0
frame.cap_len 0
frame.marked 0
caplen 66 42
timestamp 66 1584945934.045301000