XSLT 转义 HTML 实体代码 (< &#62)

XSLT escape HTML Entity Codes (&#60; &#62)

如何从 XSLT 中的 <![CDATA[&#60;ul&#62;&#60;li&#62;Linienfl&#252;ge&#60;/li&#62;&#60;/ul&#62;]]> 转义某些 HTML 实体代码?

输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Test.xsl"?>
<re>
  <bl><![CDATA[&#60;ul&#62;&#60;li&#62;Linienfl&#252;ge&#60;/li&#62;&#60;/ul&#62;]]></bl>
</re>

XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="re">
        <text>  
        <xsl:text >&lt;![CDATA[</xsl:text>
            <xsl:value-of disable-output-escaping="yes" select = "bl/."/>
        <xsl:text >]]&gt;</xsl:text>         
        </text>
    </xsl:template>
</xsl:stylesheet>

输出:

<text>
  <![CDATA[&#60;ul&#62;&#60;li&#62;Linienfl&#252;ge&#60;/li&#62;&#60;/ul&#62;]]>
</text>

预期输出:

<text>
    <![CDATA[<ul><li>Linienflüge</li></ul>]]>
</text>

在 XSLT 3 中,您可以使用

  <xsl:output cdata-section-elements="text"/>

  <xsl:template match="re">
    <text>
      <xsl:value-of select="parse-xml-fragment(bl) => parse-xml-fragment() => serialize(map { 'method' : 'xml' })"/>
    </text>
  </xsl:template>

XSLT 可在各种平台上使用,例如 Java 通过 Saxon HE 9.8 或更高版本,在 .NET 上通过 Saxon HE 的 .NET 版本,在 JavaScript 和 Node.js 通过Saxon-JS 2 和 C/C++ 与 PHP 和 Python 通过 Saxon-C 绑定。 Altova 在其各种产品(如 XMLSpy)中也支持 XSLT 3。

对于 XslCompiledTransform,您可以设置扩展函数 (https://github.com/martin-honnen/ParseXmlSerializeXslCompiledTransform/blob/master/ParseXmlSerializeXslCompiledTransform/XslCompiledTransformExtensions.cs#L10):

   public class MyExtensions
    {
        public static XPathNavigator ParseXmlFragment(string xml)
        {
            using (StringReader sr = new StringReader(xml))
            {
                using (XmlReader xr = XmlReader.Create(sr, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Fragment }))
                return new XPathDocument(xr).CreateNavigator();
            }
        }

        public static string Serialize(XPathNavigator node)
        {
            using (StringWriter sw = new StringWriter())
            {
                using (XmlWriter xw = XmlWriter.Create(sw, new XmlWriterSettings() { OmitXmlDeclaration = true, Indent = false }))
                {
                    node.WriteSubtree(xw);
               
                }
                return sw.ToString();
            }
        }
    }

用于

       XslCompiledTransform processor = new XslCompiledTransform();

        processor.Load("XSLTFile1.xslt");

        XsltArgumentList xsltArgumentList = new XsltArgumentList();
        xsltArgumentList.AddExtensionObject("http://example.com/mf", new MyExtensions());

        using (StringReader sr = new StringReader(xml))
        {
            using (XmlReader xr = XmlReader.Create(sr))
            {
                processor.Transform(xr, xsltArgumentList, Console.Out);
            }
        }

并在 XSLT 中调用

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="mf">
  
  <xsl:output method="xml" cdata-section-elements="text"/>

  <xsl:template match="re">
    <text>
      <xsl:value-of select="mf:Serialize(mf:ParseXmlFragment(mf:ParseXmlFragment(bl)))"/>
    </text>
  </xsl:template>
  
</xsl:stylesheet>