我想首先说我不擅长XPATH,这是我向你们寻求帮助的主要原因。
所以我今天正在努力尝试" group",或者说,基于他们两个共享ID的XML文件中的一些数据。在朋友的帮助下,我设法做到了这一点,但这是漫长的啰嗦,我确信必须有一个更简单/更清洁的方式。下面是我使用的XML,XSLT和所需的输出:
<Dude>
<ID>768</ID>
<Name>Mr Dude Man</Name>
</Dude>
...
<Basket>
<CustomerID>768</CustomerID>
<Purchases>
<PurchasedItem>
<ItemID>736383-2</ItemID>
<ItemName>XSLT Training</ItemName>
<ItemType>Book</ItemType>
<ItemQuantity>2</ItemQuantity>
</PurchasedItem>
<PurchasedItem>
<ItemID>736383-2</ItemID>
<ItemName>Candy</ItemName>
<ItemType>Consumable</ItemType>
<ItemQuantity>1</ItemQuantity>
</PurchasedItem>
</Purchases>
</Basket>
我使用的XSLT:
<xsl:apply-templates select="Dude"/>
<xsl:template match="Dude">
{Name} has purchased:
<xsl:apply-templates select="Basket[Basket/CustomerID = ../Dude/ID]"/>
</xsl:template>
<xsl:template match="Basket">
{ItemName}
</xsl:template>
在上面的示例中,每个Dude
都可以有一个篮子,篮子上有一个customerID
,用于识别篮子所有者。假设两个节点彼此一样深。我将如何使用<apply-templates/>
上的xpath来产生以下结果:
PS。不要太担心实际输出,我只是想知道在使用apply-templates
Mr Dude Man has purchased: XSLT Training, Candy
编辑:忘记我使用的XSLT ......现在我感到困惑的是,这是最好的方法吗?有两个单独的比赛。同样在谓词中我需要../
或谓词假设我从匹配的位置开始,例如:Dude
答案 0 :(得分:2)
像这样进行交叉引用的有效方法是使用密钥:
<xsl:key name='kBasket' match="Basket" use="CustomerID" />
然后你可以这样做:
<xsl:template match="/">
<xsl:apply-templates select="/Full/Path/To/Dude" />
</xsl:template>
<xsl:template match="Dude">
{Name} has purchased:
<xsl:apply-templates select="key('kBasket', ID)"/>
</xsl:template>
<xsl:template match="Basket">
<-- Any per-basket stuff could be output here -->
<xsl:apply-templates select="Purchases/PurchasedItem" />
</xsl:template>
<xsl:template match="PurchasedItem">
<xsl:value-of select="ItemName" />
</xsl:template>
<小时/> 原始尝试的问题在于谓词中的所有路径都与
Basket
相关(并且您没有到达Basket
的必要路径,因此节点集已经为空在那时候)。正确的方法是这样的:
<xsl:apply-templates select="/Absolute/Path/To/Basket[CustomerID = current()/ID]"/>
但关键方法更可取,因为它更有效。