我有一个要求,我需要在CDATA中替换特定标签。 例如,
<MASTER_COMMENTS>
<![CDATA[<pre> Nice Work done </pre>]]>
</MASTER_COMMENTS>
到
<MASTER_COMMENTS>
<![CDATA[<span> Nice Work done </span>]]>
</MASTER_COMMENTS>
使用XSLT子模板。
你能帮我写一下吗?
我尝试了以下但是它无效
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata-section-elements="//MASTER_COMMENTS"/>
<xsl:template match="pre">
<span><xsl:value-of select="."/></span>
</xsl:template>
答案 0 :(得分:1)
<xsl:template match="pre">
将不会匹配输入中的任何内容,因为CDATA部分包含纯文本数据,而不包含XML标记。
如果可以,请在两次传递中进行转换:首先,禁用MASTER_COMMENTS
上的输出转义并将结果保存到文件中;然后将生成的文件作为“普通”XML处理。
或者,您可以尝试使用字符串函数处理内容,例如:
<xsl:template match="MASTER_COMMENTS">
<xsl:copy>
<xsl:value-of select="substring-before(., '<pre>')" />
<xsl:text><span></xsl:text>
<xsl:value-of select="substring-before(substring-after(., '<pre>'),'</pre>') " />
<xsl:text></span>></xsl:text>
<xsl:value-of select="substring-after(., '</pre>') " />
</xsl:copy>
</xsl:template>
请注意,此示例假定处理后的文本中只有一个pre
“元素”。
答案 1 :(得分:1)
这是一个使用parse-xml
和serialize
来实现要求的XSLT 3.0样式表,它对Saxon 9.7 HE工作正常:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:output cdata-section-elements="MASTER_COMMENTS"/>
<xsl:template match="MASTER_COMMENTS">
<xsl:copy>
<xsl:variable name="content">
<xsl:apply-templates select="parse-xml(.)"/>
</xsl:variable>
<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($content, $ser-params/*)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="pre">
<span>
<xsl:apply-templates/>
</span>
</xsl:template>
</xsl:stylesheet>
输出
<?xml version="1.0" encoding="UTF-8"?><MASTER_COMMENTS><![CDATA[<span> Nice Work done </span>]]></MASTER_COMMENTS>
答案 2 :(得分:0)
嗯,你可以,但是你必须使用文本替换而不是模板匹配...请注意,如果您可能没有<pre>
或甚至多于一个的情况,这将非常困难这样的标签要被替换。如果这是你的样式表主要是关于什么,我建议使用文本转换
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:text><TOP></xsl:text>
<xsl:apply-templates/>
<xsl:text></TOP></xsl:text>
</xsl:template>
<xsl:template match="MASTER_COMMENTS">
<xsl:text><MASTER_COMMENTS></xsl:text>
<xsl:value-of select="."/>
<xsl:text></MASTER_COMMENTS></xsl:text>
</xsl:template>
</xsl:transform>
使内容可用作“文本”,然后使用该文本作为xml输入进行转换,然后可以使用普通模板匹配CDATA部分中的内容。
对于文本方法,请参阅michael.hor257k的答案。
答案 3 :(得分:0)
如果包含XML标记的节点被错误地标记为CDATA,那么XML解析器将只返回字符数据,并且要提取标记,您需要将此字符数据放入第二阶段的解析。您可以通过调用parse-xml()函数在XSLT 3.0中执行此操作;在其他XSLT处理器中,您可以使用扩展功能执行相同的操作。