0

我有一个这样的 XML 文档:

(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 驱动。

4

1 回答 1

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,它应该会按预期返回DavidAlex(尽管如果您需要在此处换行,则需要添加额外的代码)

<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()在末尾删除 ,因为在这种情况下,内置模板无论如何都会输出元素的文本。

于 2012-11-09T09:26:14.620 回答