给出如下的XML
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<root>
<config>
<kids block="A">
<owner name="bob"/>
<owner name="alice"/>
</kids>
<kids block="B">
<owner name="Jimmy"/>
<owner name="Bimmy"/>
</kids>
<kids block="C">
<owner name="Johnny"/>
</kids>
</config>
<objects>
<object owner="bob">
<name>fish</name>
<value>200</value>
<part>head</part>
<part>tail</part>
</object>
<object owner="alice">
<name>cat</name>
<value>100</value>
<part>claws</part>
<part>head</part>
<part>tail</part>
</object>
<object owner="Jimmy">
<name>DoubleDragon</name>
<value>0</value>
<part>dragon</part>
</object>
</objects>
</root>
我希望得到以下内容
Output:
A - bob - fish
alice - cat
B - Jimmy - DoubleDragon
按每个块列出所有对象名称,然后按每个所有者列出。每个所有者只有一个对象,所以这不会有问题。
是否可以在XSL 1.0中生成这样的输出?
我通过无效for-each
获得的是通过每个区块然后通过其所有者并搜索<objects>
部分中的每个所有者。但这不允许花哨的分层输出,而是我得到
A - bob - fish
A - alice - cat // note the duplicate A block name
B - Jimmy - DoubleDragon
我使用的当前XSL
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:for-each select="/root/config/kids/owner">
<xsl:variable name="ownername" select="./@name"/>
<xsl:text>
</xsl:text>
<xsl:variable name="ownedObject" select="/root/objects/object[@owner=$ownername]"/>
<xsl:if test="$ownedObject">
<xsl:value-of select="../@block"/> <xsl:text>-</xsl:text>
<xsl:value-of select="./@name"/> <xsl:text>-</xsl:text>
<xsl:value-of select="$ownedObject/name/text()"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
我通过无效的每个人获得的是通过每个区块然后通过其所有者并搜索该区域中的每个所有者。但这不允许花哨的分层输出,而是我得到......
反过来做。迭代kids
元素,并为每个元素迭代匹配的objects/object
元素。
答案 1 :(得分:1)
首先,我建议您使用 key 将对象链接到其所有者。
现在,为了达到想要的结果,你可以做到:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />
<xsl:key name="obj" match="object" use="@owner" />
<xsl:template match="/root">
<!-- for each block that has actual owners -->
<xsl:for-each select="config/kids[key('obj', owner/@name)]">
<!-- for each actual owner in this block -->
<xsl:for-each select="owner[key('obj', @name)]">
<xsl:choose>
<!-- for the first owner in this block -->
<xsl:when test="position()=1">
<xsl:value-of select="../@block"/>
<xsl:text> - </xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text> - </xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="@name"/>
<xsl:text> - </xsl:text>
<xsl:value-of select="key('obj', @name)/name"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
请注意嵌套的xsl:for-each
指令,以确保position()函数在当前块的上下文中运行。
另一种方法是处理对象,并由其所有者的块处理group。