我想使用 XSLT 将一个 XML 文件转换为另一个 XML 文件,并用属性替换某些 XML 元素的 CDATA。
我还需要保留换行符,当然我需要将在CDATA内容中找到的那些转换为“ ”.
例如,如果我有:
<description>
This is a description on
more than one line
</description>
我想要得到以下结果:
<description value="This is a description on
 more than one line"/>
我编写了以下 XSL 文件来执行此操作:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="new-line" select="' '" />
<xsl:template name="writeParam" match="/">
<xsl:choose>
<xsl:when test="description">
<xsl:element name="description">
<xsl:variable name="temp">
<xsl:value-of select="description"/>
</xsl:variable>
<xsl:attribute name="value">
<xsl:value-of select="translate($temp, $new-line, '
')" />
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
但是我得到了以下结果:
<description value=" This is a description on more than one line "/>
似乎翻译函数从未被调用过,为什么它不起作用?
你的translate()调用是没有意义的,因为它用字符U+000A(换行符)替换字符U+000A(换行符)。
您的实际输出与所需输出有两个不同之处:
(a) Saxon 选择使用十进制字符引用 (
) 而不是十六进制字符引用 (

) 来序列化换行符。它们是完全等价的,任何 XML 解析器都会以相同的方式处理它们。如果您真的关心,Saxon 的商业版本可以选择控制它。但我认为所有最近的撒克逊版本都使用十六进制形式。
(b) 值开头和结尾的换行符和空格已保留。如果你想修剪它,你可以使用
replace()
函数,例如:replace($input, '^\s*', '') => replace('\s*$', '')
.
还要注意,您的代码非常冗长。代码:
<xsl:choose>
<xsl:when test="description">
<xsl:element name="description">
<xsl:variable name="temp">
<xsl:value-of select="description"/>
</xsl:variable>
<xsl:attribute name="value">
<xsl:value-of select="translate($temp, $new-line, '
')" />
</xsl:attribute>
</xsl:element>
</xsl:when>
</xsl:choose>
可以写成:
<xsl:for-each select="description">
<description value="{translate(., $newline, '
')}"/>
</xsl:for-each>