2011-11-13 30 views
1

我一直在争取这个XSL(Saxon/Java)代码几个小时,现在仍然无法确定。我变窄问题降低到这个片段:xsl:element + xsl:function = weirdness? (Saxon,Java)

<xsl:function name="my:fff" > 
    <xsl:element name="p0"> 
    <p1 aaa='AAA' /> 
    </xsl:element> 
</xsl:function> 

<xsl:function name="my:ggg"> 

    <xsl:variable name="v" select="my:fff()" /> 

    <!-- Debug messages --> 
    <xsl:message> 
    $v   '<xsl:sequence select="$v" />' 
    $v/*  '<xsl:sequence select="$v/*" />' 
    $v/*/@aaa '<xsl:value-of select="$v/*/@aaa" />' 
    $v/p0  '<xsl:sequence select="$v/p0" />' 
    </xsl:message> 
    ... 
</xsl:function> 

由在my:ggg打印的输出如下所示:

$v   '<p0><p1 aaa="AAA"/></p0>' 
    $v/*  '<p1 aaa="AAA"/>' 
    $v/*/@aaa 'AAA' 
    $v/p0  '' 

前三行的罚款。但是输出空字符串的第四行很奇怪。我的意思是,如果$v<p0><p1 aaa="AAA"/></po>(如第一行所示)那么为什么$v/p0不是<p1 aaa="AAA"/>

我错过了什么?

+2

'$ v'是'my:fff'返回的元素,所以它*是* '包含子元素的标签。 '$ v/p0'试图选择一个''作为'$ v'中的标签的子元素,因为'$ v'选择的标签''不包含'',所以它是空的。 – rsp

+0

@rsp - 你应该让这个答案,因为它*是答案。 –

+0

@唐,确定完成:) – rsp

回答

1

如果my:fff()函数返回一个文档节点 - 而不是一个元素(p0本身没有p0子元素),那么您的推理是可以的。

所以,如果你改变了功能,如下所示:

<xsl:function name="my:fff" as="document-node()" > 
     <xsl:document> 
     <xsl:element name="p0"> 
      <p1 aaa='AAA' /> 
     </xsl:element> 
     </xsl:document> 
</xsl:function> 

而彻底转型将是:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:sequence select="my:ggg()"/> 
</xsl:template> 

<xsl:function name="my:fff" as="document-node()" > 
     <xsl:document> 
     <xsl:element name="p0"> 
      <p1 aaa='AAA' /> 
     </xsl:element> 
     </xsl:document> 
</xsl:function> 

<xsl:function name="my:ggg"> 
    <xsl:variable name="v" select="my:fff()" /> 
    <!-- Debug messages --> 
    <xsl:message> 
     $v   ' 
     <xsl:sequence select="$v" /> 
     '  $v/*  ' 
     <xsl:sequence select="$v/*" /> 
     '  $v/*/@aaa ' 
     <xsl:value-of select="$v/*/@aaa" /> 
     '  $v/p0  ' 
     <xsl:sequence select="$v/p0" />' 
    </xsl:message>  ... 
</xsl:function> 
</xsl:stylesheet> 

然后在任何XML文档应用此变换(未使用) ,现在生成以下调试输出

 $v   '<p0><p1 xmlns:my="my:my" aaa="AAA"/></p0>' 
    $v/*  '<p0><p1 xmlns:my="my:my" aaa="AAA"/></p0>' 
    $v/*/@aaa '' 
    $v/p0  '<p0><p1 xmlns:my="my:my" aaa="AAA"/></p0>' 

这可能是你想要什么,用aaa属性,它需要的例外,因为要访问:$v/*/*/@aaa

1

$vmy:fff返回的元素,所以它标签<p0>包括儿童。 $v/p0尝试选择<p0>作为$v中标记的子项,该标记为空,因为由$v选择的标记<p0>不包含<p0>

1

你会发现很容易诊断这类问题,如果你做的还是宣告说法习惯并返回一个函数的类型。这会迫使你考虑我的:fff回报。在这种情况下,它是一个(无父母)元素节点:您可以声明结果为as="element(p0)"。然后它会更清楚地表明p0元素不可能有任何p0子元素,因此my:fff()/p0可能是错误的。

相关问题