XSLT 将特定节点下的 xml 块转换为该节点的 xml-转义内容
XSLT convert xml block under a specific node to xml-escaped content of that node
任何有关如何解决以下问题的想法都将不胜感激。
输入:
<p>
<div>
Original<br/>This is the original <b>acid</b>, a hydroxy monocarboxylic <span class="hl1">acid</span>.
</div>
</p>
期望的输出:
<p>
<div>
Original<br/>This is the original <b>acid</b>, a hydroxy monocarboxylic <span class="hl1">acid</span>.
</div>
</p>
尝试 1:
`<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output omit-xml-declaration="yes" indent="no" encoding="UTF-8"/>
<!--The identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:copy>
<xsl:value-of select="/" disable-output-escaping="no"/>
</xsl:copy>
</xsl:template>
`
尝试 2:
作为替代方案,我考虑将子元素的内容放入 CDATA 包装器中。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output omit-xml-declaration="yes" indent="no" encoding="UTF-8"/>
<!--The identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:value-of select="/" />
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</xsl:template>
但这并没有给我我想要的。
有人有更好的主意吗?我正在使用 XSLT 2.0
这是一个使用 XSLT 3.0 serialize()
的建议,Saxon 9.6 HE、PE 和 EE 都支持它:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:copy>
<xsl:apply-templates mode="serialize"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()" mode="serialize">
<xsl:variable name="ser-params">
<output:serialization-parameters xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
<output:omit-xml-declaration value="yes"/>
</output:serialization-parameters>
</xsl:variable>
<xsl:value-of select="serialize(., $ser-params/*)"/>
</xsl:template>
</xsl:stylesheet>
对于旧版本的 Saxon 9,您可以使用扩展函数序列化,如 http://xsltransform.net/pPqsHTx:
所示
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output name="inline" omit-xml-declaration="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:copy>
<xsl:apply-templates mode="serialize"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()" mode="serialize">
<xsl:value-of xmlns:saxon="http://saxon.sf.net/" select="saxon:serialize(., 'inline')"/>
</xsl:template>
</xsl:stylesheet>
如果您将 xsl:value-of
更改为 xsl:copy-of
并调整 select
:
,您的第二次尝试应该会成功
<xsl:template match="div">
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:copy-of select="node()" />
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</xsl:template>
任何有关如何解决以下问题的想法都将不胜感激。
输入:
<p>
<div>
Original<br/>This is the original <b>acid</b>, a hydroxy monocarboxylic <span class="hl1">acid</span>.
</div>
</p>
期望的输出:
<p>
<div>
Original<br/>This is the original <b>acid</b>, a hydroxy monocarboxylic <span class="hl1">acid</span>.
</div>
</p>
尝试 1:
`<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output omit-xml-declaration="yes" indent="no" encoding="UTF-8"/>
<!--The identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:copy>
<xsl:value-of select="/" disable-output-escaping="no"/>
</xsl:copy>
</xsl:template>
`
尝试 2: 作为替代方案,我考虑将子元素的内容放入 CDATA 包装器中。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output omit-xml-declaration="yes" indent="no" encoding="UTF-8"/>
<!--The identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:value-of select="/" />
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</xsl:template>
但这并没有给我我想要的。 有人有更好的主意吗?我正在使用 XSLT 2.0
这是一个使用 XSLT 3.0 serialize()
的建议,Saxon 9.6 HE、PE 和 EE 都支持它:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:copy>
<xsl:apply-templates mode="serialize"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()" mode="serialize">
<xsl:variable name="ser-params">
<output:serialization-parameters xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
<output:omit-xml-declaration value="yes"/>
</output:serialization-parameters>
</xsl:variable>
<xsl:value-of select="serialize(., $ser-params/*)"/>
</xsl:template>
</xsl:stylesheet>
对于旧版本的 Saxon 9,您可以使用扩展函数序列化,如 http://xsltransform.net/pPqsHTx:
所示<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output name="inline" omit-xml-declaration="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:copy>
<xsl:apply-templates mode="serialize"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()" mode="serialize">
<xsl:value-of xmlns:saxon="http://saxon.sf.net/" select="saxon:serialize(., 'inline')"/>
</xsl:template>
</xsl:stylesheet>
如果您将 xsl:value-of
更改为 xsl:copy-of
并调整 select
:
<xsl:template match="div">
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:copy-of select="node()" />
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</xsl:template>