解析重复元素的特定实例的大型XML文件

时间:2014-01-09 19:17:23

标签: xml parsing sed

我有一个非常大的XML文件,我需要从中提取一些信息。我一直试图用sed脚本来做这件事,但我遇到了一些问题。实际上有两个版本的同一个XML文件,一个格式很好,一个只是一个巨大的单行XML。我对每个人都有不同的问题。

格式化文件:

我想从中提取数据的一个元素叫做<name>,但是这个元素有多个实例,我只想要数据在一个特定的上下文中。这就是我的意思:

XML看起来像这样:

 <object uid="1234567890-00000000">
   <name>Object Name</name>
   <country>United States</country>
   <state>Texas</state>
   <county>Travis</county>
   <timeZone>-06:00</timeZone>
   <datum uid="datum_UID">
     <name>Datum Name</name>
     <code>DUID</code>
   </datum>
 </object>

我的最终目标是生成一个两列,空白分隔的文件,其中包含第一列中的对象uid和第二列中的对象name。我的第一个想法是每个单独的sed,并使用结果构建两个临时文件,然后将它们合并为一个。问题是,当sed为name元素时,我无法弄清楚如何只获取对象<name>元素,而不是基准<name>元素。

用于查找对象sed的{​​{1}}脚本似乎完美无缺:

uid

sed -n -e 's/^.*<object uid="\([-0-9]*\)">.*/\1/p' $infile > $outfile 是大型XML文件,而$infile是我想要保存生成的$outfile的地方。以下是uid的内容,显然无效,因为它与name代码的每个实例都匹配:

<name>

有没有办法用sed -n -e 's/^.*<name>\([^<]*\)<.*/\1/p' $infile > $outfile2 执行此操作?请记住,文件非常大(超过5000万行)。我发现this blog有一个我可以尝试的多行搜索,但是如果我正确理解它,这会在搜索之前将所有行连接到保持缓冲区,而我对{{ {1}}要知道50mil +行是否真的非常糟糕。

单行文件:

我尝试使用一个sed脚本使用单行文件一步完成所有操作,但我最终只获得了最后一个匹配作为输出。这是我用过的sed脚本:

sed

我想我知道为什么这个表达式不起作用(开头的sed和结尾匹配我想要的数据之前/之后的所有内容),但我无法修复它。我在表达式中尝试了一些变化,但我从来没有得到我正在寻找的结果。要么它只打印最后一个结果,要么打印整行(在这种情况下是整个文件)。如何解析单行文件中的每个匹配?

1 个答案:

答案 0 :(得分:1)

以下是使用XML解析工具xmlstarlet

的方法
xmlstarlet sel -t -m //object -v @uid -nl -v name -nl test.xml  | paste - -
1234567890-00000000 Object Name
2   second

给出这个“test.xml”:

<objects>
<object uid="1234567890-00000000">
   <name>Object Name</name>
   <country>United States</country>
   <state>Texas</state>
   <county>Travis</county>
   <timeZone>-06:00</timeZone>
   <datum uid="datum_UID">
     <name>Datum Name</name>
     <code>DUID</code>
   </datum>
 </object>
<object uid="2">
   <name>second</name>
   <datum uid="datum_UID">
     <name>not me</name>
   </datum>
 </object>
</objects>