我想将元素下的CDATA转换为属性值并保留新行

问题描述 投票:0回答:1

我想使用 XSLT 将一个 XML 文件转换为另一个 XML 文件,并用属性替换某些 XML 元素的 CDATA。

我还需要保留换行符,当然我需要将在CDATA内容中找到的那些转换为“ ”.

例如,如果我有:

<description>
  This is a description on
  more than one line
</description>

我想要得到以下结果:

<description value="This is a description on&#xA;   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="'&#10;'" /> 

  <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, '&#xA;')" />
             </xsl:attribute>               
          </xsl:element>
       </xsl:when>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

但是我得到了以下结果:

<description value="&#10;   This is a description on&#10;   more than one line&#10;"/>

似乎翻译函数从未被调用过,为什么它不起作用?

xslt xslt-2.0 saxon
1个回答
0
投票

你的translate()调用是没有意义的,因为它用字符U+000A(换行符)替换字符U+000A(换行符)。

您的实际输出与所需输出有两个不同之处:

(a) Saxon 选择使用十进制字符引用 (

&#10;
) 而不是十六进制字符引用 (
&#xa;
) 来序列化换行符。它们是完全等价的,任何 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, '&#xA;')" />
             </xsl:attribute>               
          </xsl:element>
       </xsl:when>
    </xsl:choose>

可以写成:

<xsl:for-each select="description">
  <description value="{translate(., $newline, '&#xa;')}"/>
</xsl:for-each>
© www.soinside.com 2019 - 2024. All rights reserved.