【问题标题】:Filtering XML while preserving its structure在保留其结构的同时过滤 XML
【发布时间】:2010-11-17 09:09:30
【问题描述】:

作为过滤过程的一部分,我想从 XML 文档中删除某些标签,但我无法修改 XML 的外观或结构。

输入的 XML 以字符串形式出现,例如:

<?xml version="1.0" encoding="UTF-8"?>
<main>
    <mytag myattr="123"/>
    <mytag myattr="456"/>
</main>

并且输出需要删除属性值为 456 的 mytag

<?xml version="1.0" encoding="UTF-8"?>
<main>
    <mytag myattr="123"/>
</main>

差异应该只将删除的标签显示为输入和输出之间的差异

我研究过 SAX、StAX 和 JAXB,但似乎无法以与使用这些 API 中的任何一个输入相同的格式输出 XML。相反,它们将形成结构良好的 XML,具有适当的缩进和空格,有时会显示与输入的差异。

我当前的方法使用正则表达式,但不是很健壮,因为它没有考虑所有可能的构造上述 XML 的方法。比如要匹配属性值:

myAttr\s*=\s*"([^"]*)"

这适用于上面的示例,但对于这个 XML 标记将不起作用:

<mytag myattr=
    123></mytag>

在这种情况下,正则表达式真的是最好的选择吗?

【问题讨论】:

    标签: java xml parsing


    【解决方案1】:

    不要使用正则表达式来解析 XML! 你已经知道尝试时会发生什么,I have a spiel on why this is

    在您的情况下,您应该使用XSLT。一个 XSLT 文件来做你想做的事情是非常简单和容易理解的。基本上是这样的:

    <xsl:template match="mytag[@myattr=123]">
    </xsl:template>
    <xsl:template match="*|@*">
      <xsl:copy>
        <xsl:apply-templates select="*|@*" />
      </xsl:copy>
    </xsl:template>
    

    只要不是mytag 属性为myattr=123 的元素,它就会复制任何元素。

    我在你的示例文件上对其进行了测试,得到了你说你想要的输出。

    现在,关于如何在 Java 中使用 XSLT,看起来像 an entire book has been written on the subject。您可能可以使用您最喜欢的任何 XML 库。我以前从未真正将 XSLT 与 Java 一起使用,所以我不能告诉你哪个库最容易使用。

    【讨论】:

    • 我将看看 XSLT,但它会保留输入 XML 的结构。我给出的示例格式正确,但可以想象示例 XML 都在一行中。输出是否也都在一行上?
    • @Alex Spurling:这应该完全不相关,XML 是关于数据的,而不是关于序列化格式的。为什么它对您很重要?
    • 因为他使用的是不支持 XML 的差异工具。
    • 我完全同意,我通常不愿意在这种情况下使用正则表达式。但是,需求总是喜欢与最佳实践相冲突,在这种情况下,我们需要接收 XML 客户端,删除敏感信息,然后将其转发给不希望我们更改 XML 格式的另一个客户端。实际上,我已经对 StAX 进行了更多试验,似乎可以以与输入相同的格式输出和 XML 流。如果可行,我将为这个问题创建一个新的答案。它应该比我的正则表达式解决方案好很多!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-06-23
    • 2015-10-15
    • 2012-03-08
    相关资源
    最近更新 更多