<xsl:copy-of select="..."/> 怪异(或者如何在 XPath 1.0 中将属性转换为字符串)

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

好的,想象一个场景,您想要创建一个元素

Foo
,有时包含文本,有时包含元素,例如

所以有时输出需要看起来像这样(我嵌入了一个

sortOrder
元素)

<root>
  <Foo>
    <sortOrder value="3" />
  </Foo>
  <Foo>
    <sortOrder value="2" />
  </Foo>
  <Foo>
    <sortOrder value="2" />
  </Foo>
</root>

有时它需要是像这样的简单文本值

<root>
  <Foo>3</Foo>
  <Foo>2</Foo>
  <Foo>2</Foo>
</root>

(可怕的是,我没有发明这个模式)

所以让我们补充一些意见......

<root>
  <element>
    <sortOrder value="3"/>
  </element>
  <element>
     <sortOrder value="2"/>
  </element>
  <element>
     <sortOrder value="2"/>
  </element>
</root>

并编写一个模板来制作 Foo 元素

   <xsl:template name="makeFoo">
      <xsl:param name="value"/>
      <Foo>
         <xsl:copy-of select="$value"/>
      </Foo>
   </xsl:template>

这是第一个示例的整个 xslt,它有效!!

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  exclude-result-prefixes="xsl">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="/">
      <root>
         <xsl:for-each select="root/element">
            <xsl:call-template name="makeFoo">
               <xsl:with-param name="value" select="sortOrder"/>
            </xsl:call-template>
         </xsl:for-each>
      </root>
   </xsl:template>
   
   <xsl:template name="makeFoo">
      <xsl:param name="value"/>
      <Foo>
         <xsl:copy-of select="$value"/>
      </Foo>
   </xsl:template>

</xsl:stylesheet>

让我们尝试一下第二个输出的明显效果......(使用相同的“库函数 makeFoo”)

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  exclude-result-prefixes="xsl">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="/">
      <root>
         <xsl:for-each select="root/element">
            <xsl:call-template name="makeFoo">
               <xsl:with-param name="value" select="sortOrder/@value"/>
            </xsl:call-template>
         </xsl:for-each>
      </root>
   </xsl:template>
   
   <xsl:template name="makeFoo">
      <xsl:param name="value"/>
      <Foo>
         <xsl:copy-of select="$value"/>
      </Foo>
   </xsl:template>

</xsl:stylesheet>

啊...几乎...这就是这样..

它复制了属性...聪明...但不是我想要的。

<root>
  <Foo value="3" />
  <Foo value="2" />
  <Foo value="2" />
</root>

那么我怎样才能得到我想要的......

我尝试过...

<xsl:with-param name="value" select="sortOrder/@value/text()"/>

不(毫不奇怪,那里没有文本节点)

这个..

<xsl:with-param name="value">
   <xsl:value-of select="sortOrder/@value"/>
</xsl:with-param>

有效!!!

大概我们正在强制 xsl 生成一个传递然后复制的文本节点。

但是有没有办法在选择中做到这一点?即在 XPath 表达式中?

xslt-1.0
1个回答
0
投票

属性没有子文本节点。要获取属性的 string-value,您应该使用

xsl:value-of
指令。如果您必须使用
xsl:copy
(为什么?),您首先需要将属性转换为字符串。在你的例子中,这(可能)意味着:

<xsl:with-param name="value" select="string(sortOrder/@value)"/>

我希望这能回答你的问题,我觉得这个问题很令人困惑。

© www.soinside.com 2019 - 2024. All rights reserved.