2012-11-08 51 views
0

我有一个这样的XML文档:XSLT1选择兄弟姐妹的孩子节点值

(P为先前定义)

<p:Players> 
<p:Player> 
<p:Name>David</p:Name> 
<p:Club> 
<p:Name>Madrid</p:Name> 
</p:Club> 
<p:PreviousClubs> 
<p:Club><p:Name>Milan</p:Name></p:Club> 
<p:Club><p:Name>Manchester</p:Name></p:Club> 
</p:PreviousClubs> 
</p:Player> 
<p:Player> 
<p:Name>Alex</p:Name> 
<p:Club> 
<p:Name>Madrid</p:Name> 
</p:Club> 
<p:PreviousClubs> 
<p:Club><p:Name>Birmingham</p:Name></p:Club> 
<p:Club><p:Name>Manchester</p:Name></p:Club> 
</p:PreviousClubs> 
</p:Player> 
<p:Player> 
<p:Name>Fred</p:Name> 
<p:Club> 
<p:Name>Madrid</p:Name> 
</p:Club> 
<p:PreviousClubs> 
<p:Club><p:Name>Milan</p:Name></p:Club> 
<p:Club><p:Name>Birmingham</p:Name></p:Club> 
</p:PreviousClubs> 
</p:Player> 
</p:Players> 

我想获得的所有谁以前已经将球员的名字为特定的俱乐部效力。

这是我迄今为止,但它不捡东西了:

/*[1]/p:Player[p:PreviousClubs/p:Club/p:Name='Manchester']/p:Name/text() 

我希望回到

David 
Alex 

但我什么也没得到

可有人看看我要去哪里错了?

p:的命名空间及其前缀是正确的 - 在其他地方使用并且很好。我觉得我的逻辑围绕选择特定的父节点是错误的...

我需要坚持XSLT 1.0作为其BizTalk驱动。

+2

我认为这可能与命名空间有关。在您的XML示例中,您根本没有指定名称空间,因此所有元素都属于NO名称空间。如果您在XSLT的xpath表达式中使用** p **的名称空间前缀,那么它将查找为** p **前缀定义的名称空间-Uri内的元素。你的输入XML确实没有定义名称空间吗? –

+0

它确实有名称空间定义,我快速复制而不是复制和粘贴 - 命名空间不是问题,但它只是没有选择文本值。我复制并粘贴命名空间 - 我现在编辑xml,以便它匹配 – Chris

+0

啊,好的!你能不能在你的XML中显示** p **前缀的定义(即命名空间url,比如''。你显然需要检查uri与XSLT中指定的相同,如果你展示了更多的实际XSLT,以防万一问题出在其他地方,也可能有所帮助谢谢! –

回答

1

这几乎肯定是命名空间的一个问题。

在您的XML中,您使用的是名称空间前缀,但名称空间没有相应的定义。你真的应该有一个定义,像这样的根元素

<p:Players xmlns:p="mynamespace"> 

然后,你的XSLT中,你还需要确保URI的定义相同的命名空间。

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:p="mynamespace"> 

注意,前缀p不必是相同的。这是名称空间URI,这里是重要的标识符。如果URI与XML中的内容不匹配,则使用前缀时将无法找到元素。

如果因此使用XSLT,它应该返回大卫亚历预期(尽管可能需要添加额外的代码,如果你想换行点击这里)

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:p="mynamespace"> 

    <xsl:template match="/"> 
     <xsl:apply-templates 
      select="/*[1]/p:Player[p:PreviousClubs/p:Club/p:Name='Manchester']/p:Name/text()" /> 
    </xsl:template> 
</xsl:stylesheet> 

这一切都意味着您的原始XPath表达式是正确的!不过,您可以稍微简化一下,因为[1]一开始不需要。第一/文档元素相匹配,所以/*将根元素相匹配,因为你只能有良好的XML一个根元素,没有必要与索引[1]

/*/p:Player[p:PreviousClubs/p:Club/p:Name='Manchester']/p:Name/text() 

来限定它您最后也可以删除text(),因为无论如何,内置模板都会在这种情况下输出元素的文本。

+0

非常感谢! – Chris