2013-04-27 50 views
0

我有一大堆的XML文件,每个文件格式...获取XML整个元素,从搜索结果中

<?xml version="1.0" encoding="UTF-8"?> 
<A> 
    <R> 
     <B></B> 
     <Q></Q> 
     <U></U> 
    </R> 
    ... 
</A> 

我需要寻找每个字符串,并返回整个元素“R” 。问题是有字符串的新行,所以我不能使用grep -B n -A n,因为每个搜索结果前后的行数可能不同,因此每个搜索结果可能会不同。

<?xml version="1.0" encoding="UTF-8"?> 
<A> 
    <R> 
     <B>abc</B> 
     <Q>0123</Q> 
     <U>xyz</U> 
    </R> 
    <R> 
     <B> 
      qwe 
      rty 
      yui 
     </B> 
     <Q>0123</Q> 
     <U> 
      zxc 
      abc 
     </U> 
    </R> 
    <R> 
     <B>lkj</B> 
     <Q> 
      lkjhgfdsa 
      wer 
     </Q> 
     <U> 
      poixyz 
      zaq 
     </U> 
    </R> 
</A> 

如果我用grep为 “XYZ”,那么我需要......

<R> 
    <B>abc</B> 
    <Q>0123</Q> 
    <U>xyz</U> 
</R> 
<R> 
    <B>lkj</B> 
    <Q> 
     lkjhgfdsa 
     wer 
    </Q> 
    <U> 
     poixyz 
     zaq 
    </U> 
</R> 

我不反对使用其他工具如Perl,egrep的,等...完成这个。任何和所有的帮助将不胜感激。

回答

1

学习XPath并使用xml_grep2

$ xml_grep2 -x '//*[text()[contains(string(.),"xyz")]]/ancestor::R' nvanwyen.xml 

<R> 
     <B>abc</B> 
     <Q>0123</Q> 
     <U>xyz</U> 
    </R> 
<R> 
     <B>lkj</B> 
     <Q> 
      lkjhgfdsa 
      wer 
     </Q> 
     <U> 
      poixyz 
      zaq 
     </U> 
    </R> 
+0

这工作...谢谢 – nvanwyen 2013-04-28 00:29:52

1

是的,它可以在Perl中完成,例如,与xpath可执行随XML::XPath

xpath a.xml '//R[.//*[contains(text(),"xyz")]]' 

或用其他功能,如矿(这个网站不会让我链接到它),这是基于XML::LibXML

xpath-rp -e '//R[.//*[contains(text(),"xyz")]]' a.xml 

另一种选择是xmlstarlet

xmlstarlet sel -t -c '//R[.//*[contains(text(),"xyz")]]' a.xml 

PS:这只是替代daxim的答案。 我不知道xml_grep2,我会马上安装它! 重点是在这里使用XPath是一个好主意。

+0

我无法获得这两种解决方案中的任何一种。似乎都没有产生任何结果......一定是我。 – nvanwyen 2013-04-27 19:01:19