首页 > 解决方案 > 正则表达式替换xml内容java

问题描述

我需要用空字符串替换 xml 内容。

  <credential location="PropertyFileInventoryProvider" name="CLI_SESSION_PARENT_SCRIPT">&lt;cliSession xmlns="http://example.com/cfr2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" formatVersion="1" xsi:schemaLocation="http://example.com/cfr2 xdeCliSessionScript.xsd"&gt;
    &lt;/cliSession&gt;</credential>

我构建了以下正则表达式,但它不起作用。

val.replaceAll("<credential location=\"PropertyFileInventoryProvider\" name=\"CLI_SESSION_PARENT_SCRIPT\">[\\s\\S]*?</credential>", "");

标签: javaregex

解决方案


  • 使用正则表达式处理 XML 是个坏主意. 它不是前向兼容的。您的程序只是等待将来失败。有太多选择如何以语义相同的方式编写 XML,而这些选择很难被正则表达式捕获。例如,属性值可以用撇号而不是引号括起来。属性的顺序可能不同。属性前后空格的数量和类型可能不同。属性值的等号之前或之后甚至可能有空格。可以引入命名空间声明。可以引入 XML 或其他名称空间的属性。可以插入评论。当生成上述 XML 文件的程序稍作更改,并且属性的顺序发生更改时,生成的 XML 在语义上是相同的,但是您的正则表达式会中断。
  • 您的正则表达式可以简化为,[^<]而不是[\\s\\S]因为[\\s\\S]实际上是.,但您可能想要排除<.
  • 您不分配值。请记住,在 JavaString中是不可变的。为了获取替换的字符串,您需要分配返回值。所以,大概val = val.replaceAll(...)

因此,您的 Java 代码应该是:

val = val.replaceAll("<credential location=\"PropertyFileInventoryProvider\" name=\"CLI_SESSION_PARENT_SCRIPT\">[^<]*?</credential>", "");

您可以使用 XSLT 和 XPath 或 DOM 和 XPath 以更健壮的方式获得类似的结果。例如,您可以删除所有匹配的节点credential[@location="PropertyFileInventoryProvider"][@name="CLI_SESSION_PARENT_SCRIPT"]

以下 XSLT 将执行此操作:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template
        match='
            credential
                [@location="PropertyFileInventoryProvider"] 
                [@name="CLI_SESSION_PARENT_SCRIPT"]
        '
    />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
<xsl:transform>

推荐阅读