【发布时间】:2019-10-07 01:06:13
【问题描述】:
我正在尝试在 Linux 系统上使用 xmllint 从一个巨大的(>150 万行)xml 文档中提取一些特定数据,并且对 xmllint 语法不太满意。我一直在使用 grep 和 awk 非常低效地执行此操作,但我发现该系统具有 xmllint 实用程序(我从未使用过),并且我认为由于 xml 结构良好,应该有一种方法可以直接访问数据。我已经包含了 xml 文档的 sn-p,但是在缩减它时,我导致 xmllint 出现解析器错误,尽管它看起来对我来说是正确的。我想如果你足够精通 xmllint 来回答我的问题,你可能很容易找出解析器错误。
基于网络搜索,我尝试了以下语法:
cat //*/@index' | xmllint --shell stub.xml (which does return ALL of the "indexes")
and
test=$(xmllint --debug --xpath "//PTC/BPSETS/BPSET/BPS" stub.xml) (which does dump the entire BPS entry)
and
xmllint --xpath "string(//PTC/BPSETS/BPSET/@b95)" stub.xml (returns no values)
Here is the xml snippet as best as I can trim it down:
<?xml version="1.0" encoding="utf-8"?>
<PTC version="2.0" cls="2">
<BPSETS>
<BPSET define="b95">
<BPS define="88lmax">
<CRIT>
<MNBS lmt="88" />
<MXBS lmt="88" />
<MXBT red="Y" />
</CRIT>
<PNS>
<PN index="0" atv="1" bf="32203506">
<AWD cpbt="390">
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
<PN index="1" atv="1" bf="24237243">
<AWD cpbt="390">
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
<PN index="2" atv="1" bf="8136575">
<AWD cpbt="390">
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
<PN index="688" atv="1" bf="1183872">
<AWD cpbt="50" />
</PN>
</PNS>
</BPS>
<BPS define="88l6">
<CRIT>
<MNBS lmt="88" />
<MXBS lmt="88" />
<MXBT lmt="6" />
<MNBT lmt="6" />
</CRIT>
<PNS>
<PN index="0" atv="1" bf="28073582">
<AWD cpbt="150">
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
<PN index="1" atv="1" bf="16686973">
<AWD cpbt="150">
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
</PNS>
</BPS>
<BPS define="88l4">
<CRIT>
<MNBS lmt="88" />
<MXBS lmt="88" />
<MXBT lmt="4" />
<MNBT lmt="4" />
</CRIT>
<PNS>
<PN index="0" atv="1" bf="31342257">
<AWD cpbt="50">
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
<PN index="1" atv="1" bf="13761775">
<AWD cpbt="50">
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
</PNS>
</BPS>
<BPS define="88l2">
<CRIT>
<MNBS lmt="88" />
<MXBS lmt="88" />
<MXBT lmt="2" />
<MNBT lmt="2" />
</CRIT>
<PNS>
<PN index="0" atv="1" bf="16291759">
<AWD cpbt="10">
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
<PN index="1" atv="1" bf="15032283">
<AWD cpbt="10">
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
</PNS>
</BPS>
<BPS define="88l1">
<CRIT>
<MNBS lmt="88" />
<MXBS lmt="88" />
<MXBT lmt="1" />
<MNBT lmt="1" />
</CRIT>
<PNS>
<PN index="0" atv="1" bf="33278739">
<AWD>
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
<PN index="1" atv="1" bf="7261567">
<AWD>
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
<PN index="896" atv="1" bf="101540">
<AWD cpbt="10" />
</PN>
<PN index="897" atv="1" bf="3680792">
<AWD cpbt="10" />
</PN>
<PN index="898" atv="1" bf="25776896">
<AWD cpbt="10" />
</PN>
</PNS>
</BPS>
</BPSET>
<BPSET define="b94" use="b95">
<BPS define="88mx">
<PNS>
<PN index="422" atv="1" bf="11692089">
<AWD cpbt="9000" />
</PN>
<PN index="424" atv="1" bf="12200338">
<AWD cpbt="7200" />
</PN>
<PN index="427" atv="1" bf="24210225">
<AWD cpbt="6000" />
</PN>
</PNS>
<BPS>
</BPSET>
</BPSETS>
</PTC>
What I really need is a query that returns all the attribute's contained in a specific element under a specific index e.g.:
<!-- language: lang-xml -->
<PTC version="2.0" cls="2">
<PN index="0" atv="1" bf="32203506">
<AWD cpbt="390">
<BUNS ptgp="bn38" bdx="38" fawd="1" />
<BUNS ptgp="bn39" bdx="39" fawd="1" awby="38" />
</AWD>
</PN>
A query that given a PN index value (e.g. 0) would return the values of bf and cbpt…
If it were an sql query the xmllint query I'm looking for would be something like:
```sql
select bf,cbpt from PTC.BPSETS.BPSET.BPS.PNS.PN
where BPSET = "b95" AND BPS = 88lmax AND PN.index = 0.
如果你跟着我的想法走。 这里的任何指导表示赞赏。谢谢。
【问题讨论】:
-
请edit 您的问题包含您拥有的完整 XML 文件。如果可能,请证明minimal reproducible example、您尝试运行的命令以及您收到的错误消息。检查stackoverflow.com/editing-help 以获取任何格式帮助。并且不要“尖叫”,你这样做并没有帮助任何人。
-
xml sn-p 添加回正文中,我怀疑它没有经过格式检查。