【问题标题】:How to use perl to filter XML file with tags?如何使用 perl 过滤带有标签的 XML 文件?
【发布时间】:2020-03-21 10:45:38
【问题描述】:

我有一个很大的 XML 文件(2 GB),该文件包含太多需要过滤的无用数据,下面是 XML 文件的粗略结构:

(所有无用数据都替换为“useless_information”,看起来干净整洁)

<hmdb>
    <metabolite>
        <useless_information></useless_information>
        <useless_information></useless_information>
        <useless_information></useless_information>
        <useless_information></useless_information>
        ...
        <normal_concentrations>
            <useless_information></useless_information>
            <useless_information></useless_information>
            <useless_information></useless_information>
            ...
            <concentration>
                <useless_information></useless_information>
                <useless_information></useless_information>
                <useless_information></useless_information>
                <useless_information></useless_information>
                ...
                <concentration_value> 100 </concentration_value>
                <subject_age> 21 </subject_age>
                <subject_sex> male </subject_sex>
            </concentration>
            <concentration></concentration>
            <concentration></concentration>
            <concentration></concentration>
            ...
        </normal_concentrations>
    </metabolite>
    <metabolite></metabolite>
    <metabolite></metabolite>
    <metabolite></metabolite>
    <metabolite></metabolite>
    ...
</hmdb>

所以,基本上我想保留以下标签和值:concentration_value,subject_age和subject_sex,其余的都不重要,可以过滤,过滤后的XML应该是这样的:

<hmdb>
    <metabolite>
        <concentration>
            <concentration_value> 100 </concentration_value>
            <subject_age> 21 </subject_age>
            <subject_sex> male </subject_sex>
        </concentration>
        <concentration></concentration>
        <concentration></concentration>
        <concentration></concentration>
        ...
    </metabolite>
    <metabolite></metabolite>
    <metabolite></metabolite>
    <metabolite></metabolite>
    <metabolite></metabolite>
    ...
</hmdb>

我需要这个文件中的数据来继续学习(这个文件太大了,我的笔记本电脑打不开这个文件,所以我在使用之前必须过滤掉无用的数据以减小XML文件的大小) , 但我不知道如何编写 perl 脚本, 非常感谢您的帮助, 非常感谢:)

【问题讨论】:

  • 您如何决定保留&lt;normal_concentrations&gt; 节点?根据规定的标准和显示的数据,&lt;concentration&gt; 节点是否足够?
  • 您压缩示例文件的方式很好,但我希望有许多节点名称的_all_kinds 要跳过,您不知道。您知道您希望保留的所有节点的名称吗? (或者真的很简单 &lt;normal_concentrations&gt; 就这样?)
  • 嘿,谢谢你的回复,是的,我需要保留 normal_concentrations 标签,而在这个标签中,还有 3 个标签和值需要保留,“concentration_value、subject_age 和 subject_sex”,其余的都可以去掉,但是每个“代谢物”标签中都有很多“浓度”标签,我需要将所有“浓度”标签保留在不同的“代谢物”标签中。
  • 好的。但是,当您说“需要将所有“浓度”标签保留在不同的“代谢物”标签中”时,您是否也不需要保留 metabolite 节点? (作为一个结构,即使 concentration 以外的所有子节点都被删除。)期望的结果没有显示出来。
  • 哦,是的!你是对的,真的很感激!我还需要保留代谢物标签,抱歉让您感到困惑,我现在编辑问题:)

标签: xml perl


【解决方案1】:

假设你的数据样本是有代表性的(也就是说,useless_information 的所有匹配标签都在同一行)并假设你的输入数据在一个名为 input-data.xml 的文件中,下面一行 perl程序应该可以工作。我用你的样品测试了它。所以在 bash(或者对于 windows,cmd.exe)命令行输入这个

perl -nle 'while(<stdin>){if(!/useless_information/){chop; print}}' <input-data.xml >output-data.xml

这个小小的一行程序将忽略任何包含“useless_information”的行,并假设匹配的标签总是在同一行。

但是,由于我怀疑您可能要忽略几个无用的标签,因此过滤您想要的而不是您不想要的可能更有效。

perl -nle 'while(<stdin>){if(/metobolite|normal_concentrations|concentration_value|subject_age|subject_sex|concentration/){chop; print}}' <input-data.xml >output-data.xml

这还假设您已经安装了 perl,并且它(perl 的可执行文件)位于名为“PATH”的环境变量中。

现在如果你发现有时它(匹配的标签)不在同一行,那我们就得花点心思了。

HTH!

【讨论】:

  • 感谢您的回复,这是新的更新,我对您的代码进行了一些修改,达到了预期的效果!太感谢了!但是我意识到有很多“”标签没有任何价值,我可以知道如何删除那些空的“”标签吗?再次感谢您的帮助!!! :)
  • 只消除那些在同一行有配对(“”)的浓度标签会有帮助吗?如果是这样,那很容易做到。
【解决方案2】:

文件包含太多需要过滤的无用数据

http://p3rl.org/xml_grep

【讨论】:

    猜你喜欢
    • 2020-05-12
    • 2014-07-08
    • 2020-09-02
    • 1970-01-01
    • 2012-08-03
    • 2011-10-03
    • 2013-12-20
    • 2021-03-28
    • 2022-11-03
    相关资源
    最近更新 更多