从搜索结果中获取XML整个元素

时间:2013-04-27 15:46:48

标签: xml perl search grep

我有一堆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>

如果我寻找“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等其他工具来实现这一目标。任何和所有的帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

是的,它可以在Perl中完成,例如使用XML::XPath附带的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

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

答案 1 :(得分: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>