如何使用基于标签的 XML::Twig 解析器在 Unix 上清理 xml 文件 [关闭]
Posted
技术标签:
【中文标题】如何使用基于标签的 XML::Twig 解析器在 Unix 上清理 xml 文件 [关闭]【英文标题】:How to cleanup xml file on Unix using XML::Twig parser based on tags [closed] 【发布时间】:2021-01-08 12:57:09 【问题描述】:我需要从不必要的信息(重复、过时等)中清理 XML 文件。 我有具有不同命名标签的 XML 文件,但它们都具有相似的属性,我正在寻找一种解决方案,了解如何通过将参数传递给 Perl 解析器来从 XML 文件中删除一些标签。
一个示例 XML 结构是:
<Jobs>
<Job>
<JobID>ID1</JobID>
<DueDate>01-02-2008</DueDate>
</Job>
<Job>
<JobID>ID2</JobID>
<DueDate>01-02-2009</DueDate>
</Job>
<Job>
<JobID>ID3</JobID>
<DueDate>01-02-2010</DueDate>
</Job>
<Job>
<JobID>ID4</JobID>
<DueDate>01-02-2011</DueDate>
</Job>
<Job>
<JobID>ID5</JobID>
<DueDate>01-02-2012</DueDate>
</Job>
</Jobs>
现在假设我希望删除包含 JobID
标记和文本 ID3
的 Job
标记,我的 output.xml 文件将变为:
<Jobs>
<Job>
<JobID>ID1</JobID>
<DueDate>01-02-2008</DueDate>
</Job>
<Job>
<JobID>ID2</JobID>
<DueDate>01-02-2009</DueDate>
</Job>
<Job>
<JobID>ID4</JobID>
<DueDate>01-02-2011</DueDate>
</Job>
<Job>
<JobID>ID5</JobID>
<DueDate>01-02-2012</DueDate>
</Job>
</Jobs>
请帮助我使用 XML::Twig
编写代码,这可以帮助使用 Perl Based on suggestion made here 解决此任务
我需要在文件中的任何位置剪切标签并拉出它下面的所有其他标签并保存回文件(最好是同一个文件)。
我需要一个 Perl 脚本并将参数传递给它,如下所示:
将两个参数传递给脚本:
-
需要删除的标签名称,我们称之为
R_tag
嵌套在 R_tag 下的标签的名称,我们称之为R_tag_nested
我们必须传递一个嵌套标签必须等于的值才能触发R_tag
删除,在我们的例子中是ID3
我会使用这一行来调用脚本
myscript.pl?R_tag&R_tag_nested=ID3
但与此同时,我希望足够灵活,以便通过发送多个嵌套标签参数(因为 R_tag
在整个文档中相同)一次性删除 2 个或多个标签,并且命令将是:
myscript.pl?R_tag&R_tag_nested=ID3&R_tag_nested=ID5
会将此类输出提供给 output.xml 文件:
<Jobs>
<Job>
<JobID>ID1</JobID>
<DueDate>01-02-2008</DueDate>
</Job>
<Job>
<JobID>ID2</JobID>
<DueDate>01-02-2009</DueDate>
</Job>
<Job>
<JobID>ID4</JobID>
<DueDate>01-02-2011</DueDate>
</Job>
</Jobs>
我还没有开始编写它,因为我没有太多使用 XML::Twig 剪切/粘贴/修剪 XML 的经验,并且需要帮助从头开始编写这个短代码。
【问题讨论】:
【参考方案1】:你还没有确定是什么给你带来了问题,所以我假设你在问如何解决这个问题。
当您想从列表中过滤掉项目时,哈希很有用。构建以下哈希:
my %to_remove = (
"ID3" => 1,
"ID5" => 1,
);
然后,这只是遍历您可能要删除的节点、获取其文本内容并删除这些节点的问题 以下是正确的:
$to_remove$text_content
【讨论】:
是的,一个好主意,而且由于脚本的编写还没有开始——我仍在有序地提出整个想法(这可能对其他人也非常有用)该做什么以及如何正确编写代码,因为我可能需要一个 1Gb 大小的 XML 文件,其中包含 200 万个 JobID 节点,然后需要从 XML 文件中删除大约 700,000 个这样的节点。所以它必须快速运行并消耗最少的内存。所以第一步是从要删除的列表中构建一个哈希。 XML::Twig 的twig_roots
可用于通过仅构建感兴趣的子树来限制内存使用(例如,一次只有一个作业在内存中)。我更熟悉 XML::LibXML,所以我会使用 XML::LibXML::Reader 的copyCurrentNode(1)
来实现相同的结果。
我没有附加到 XML::Twig 并且很乐意使用其他任何东西,只要它能完成这项工作。但我正在努力从头开始编写代码。我可以稍后根据需要调整/修改它,但整个基础略高于我的技能。以上是关于如何使用基于标签的 XML::Twig 解析器在 Unix 上清理 xml 文件 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
流式处理和基于树的 XML 解析器在 JAVA 开始时是不是消耗相似数量的内存