使用 XSL 测试节点是否包含转义的 XML



我正在尝试清理我提供的一批XML。我需要考虑三种情况:

  1. 某些元素中包含纯文本,例如。 <item>some text</item> ,需要包装在另一个标签中,例如。 <item><p>some text</p></item>
  2. 某些元素在其中转义了 XML,例如。 <item>&lt;p>some text&lt;/p></item> ,需要在不转义的情况下输出:<item><p>some text</p></item>
  3. 一些元素已经转义了需要包装的XML,例如。 <item>some &lt;em>text&lt;/em></item>需要变得<item><p>some <em>text</em></p></item>

<item>在这两种情况下都用作容器。

我可以相对容易地满足条件 1,我可以用 disable-output-escaping 满足条件 2,但我不能用这种方法满足条件 3。

我想如果我能测试<item>中的文本是否被转义,我可以满足 2(可能 3(,但使用 contains(., '&amp;lt;') 的测试不匹配。 所以...

如何测试节点中的文本是否为转义 XML?

  1. 和 3. 两者都需要在 1. 中包装和禁用输出转义。 不会有什么坏处,所以我认为你可以用同一个模板将它们一起处理。

我没有看到明确的检查元素内容是否包含具有纯 XSLT 1.0 手段的转义元素标记,所以我只是尝试了

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
  <html>
    <body>
      <xsl:apply-templates/>
    </body>
  </html>
</xsl:template>
<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="item[not(*) and not(starts-with(., '&lt;') and substring(., string-length(.)) = '&gt;')]">
  <xsl:copy>
    <p>
      <xsl:value-of select="." disable-output-escaping="yes"/>
    </p>
  </xsl:copy>
</xsl:template>
<xsl:template match="item[not(*)
                          and starts-with(., '&lt;') and substring(., string-length(.)) = '&gt;']">
  <xsl:copy>
    <xsl:value-of select="." disable-output-escaping="yes"/>
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

哪个转换

<root>
<item>some text</item>
<item>&lt;p>some text&lt;/p></item>
<item>some &lt;em>text&lt;/em></item>
</root>

<html><body>
<item><p>some text</p></item>
<item><p>some text</p></item>
<item><p>some <em>text</em></p></item>
</body></html>

显然,它也会<item>&lt;...></item>变成<item><...></item>。您可以尝试实现更多的字符串检查,但如果没有转义 XML 片段的完整解析器,始终可以在字符串检查失败的情况下构造输入样本。

相关内容

  • 没有找到相关文章

最新更新