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

时间:2013-07-09 14:36:32

标签: xml xslt escaping libxml2 libxslt

我正在尝试清理我提供的一批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>
  4. <item>在两个实例中都用作容器。

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

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

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

1 个答案:

答案 0 :(得分:0)

  1. 和3.两者都需要包装和禁用 - 输出 - 逃逸1.不会伤害所以我认为你可以用同一个模板一起对待它们。
  2. 我没有看清楚元素内容是否包含带有纯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片段解析器,则始终可以构造字符串检查失败的输入样本。