【问题标题】:If regEx is bad for matching XML, what is the correct way?如果 regEx 不适合匹配 XML,那么正确的方法是什么?
【发布时间】:2021-09-03 14:00:54
【问题描述】:

我试图在 XML 中进行简单的字符串删除。

我想删除如下内容。

<A>
    <B>Test Name</B>
</A>

不过,必须使用所有可能的 XML。

<Test><A><B>Test Name</B></A></Test>
<Test ><A ><B >Test Name</B ></A ></Test >

<Test>
   <A>
       <B>Test Name</B>
   </A>
</Test>

等等等等

我目前得到的正则EX,很简单:

<A>\s*(\r\n|\r|\n)*\s*<B>Test Name<\/B>\s*(\r\n|\r|\n)*\s*<\/A>

每个人都说正则表达式不适合匹配 XML,这显然是。那我应该改用什么。

GC_

【问题讨论】:

  • 可能是一个 xml 解析器?
  • 例如baeldung.com/java-xml,几乎涵盖了所有这些。
  • @GarrGodfrey 我想要一些重量轻的东西。我真的不想解析整个xml,只是删除一行。
  • 这不是一行,而是一个元素及其子元素。这就是天真的正则表达式方法的众多问题之一。
  • XSLT 最适合此类任务。

标签: java xml parsing


【解决方案1】:

这种情况的最佳方法是使用 XSLT。即使使用 XSLT-1.0,这也很简单(您可以使用 Java XSLT 处理器、linux'es xsltproc 或任何其他 XSLT 处理器;每个 XSLT 处理器至少支持 XSLT-1.0):

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml"  omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
  <xsl:strip-space elements="*" />
  
  <!-- identity template - matches everything except the things matched by other templates -->
  <xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
 
  <!-- Removes the elements you do not want -->
  <xsl:template match="A[B[normalize-space(.)='Test Name']]" />

</xsl:stylesheet>

您的示例案例的输出(带有假设的根元素)将是

<Test/>
<Test/>
<Test/>

尝试使用 RegEx 很容易出错,而且根本没有好的做法。
如果可以这么简单,你为什么要让它变得复杂?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 2012-08-30
    • 1970-01-01
    相关资源
    最近更新 更多