XML
<dsInventory>
<Room>
<RoomName>kantoor 1</RoomName>
<RoomId>1376257</RoomId>
</Room>
<Room>
<RoomName>Hal</RoomName>
<RoomId>1376258</RoomId>
</Room>
<Method>
<RoomId>1376257</RoomId>
<Name>test</Name>
</Method>
<Method>
<RoomId>1376258</RoomId>
<Name>test</Name>
</Method>
</dsInventory>
XSL
<xsl:for-each select="/dsInventory/Room">
<xsl:for-each select="/dsInventory/Method">
<xsl:if test="RoomId=../RoomId">
</xsl:if>
</xsl:for-each>
</xsl:for-each>
问题
我正在尝试根据宽限期选择相应房间的方法。但是选择器../RoomId不起作用。如何从第一个获得RoomId的价值?或者选择房间方法的正确方法是什么?
答案 0 :(得分:0)
这里的问题是背景。 if
条件失败,因为它从Method
个节点的上下文运行,因此XPath表达式../RoomID
正在RoomID
上查找dsInventory
节点。没有这样的节点。
你没有说出你想要的输出,但是基于你只想迭代房间并找到每个方法的假设,试试这个:(注意我也使用模板而不是每个循环,在XSL中最好避免使用。
您可以运行它并在 this XML Playground 处查看输出。
<!-- kick things off from the point of dsInventory -->
<xsl:template match="dsInventory">
<ul><xsl:apply-templates select='Room' /></ul>
</xsl:template>
<!-- room nodes -->
<xsl:template match='Room'>
<xsl:variable name='method' select='../Method[RoomId = current()/RoomId]' />
<li>
<xsl:value-of select='concat(RoomName," (",RoomId,")")' />:
method = <xsl:value-of select='concat($method/Name," (",$method/RoomId,")")' />
</li>
</xsl:template>
答案 1 :(得分:0)
您没有指定正在使用的XSLT版本或您预期的输出。我假设您想要XSLT 1.0,想要复制文档,但在Room下添加链接的方法名称并删除方法。
此XSLT 1.0样式表......
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Method"/>
<xsl:template match="Room">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="../Method[RoomId=current()/RoomId]/Name"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
...当应用于您的样本输入文档时,将生成...
<dsInventory>
<Room>
<RoomName>kantoor 1</RoomName>
<RoomId>1376257</RoomId>
<Name>test</Name>
</Room>
<Room>
<RoomName>Hal</RoomName>
<RoomId>1376258</RoomId>
<Name>test</Name>
</Room>
</dsInventory>
使用current()函数指定相对于Room模板的序列构造函数的当前项,在本例中是Room元素。在谓词中,我们将current()/ RoomId与select表达式的Method步骤的RoomId进行比较。因此,链接的名称将复制到Room下。没有xsl:if,没有xsl:for-each,没有变量。所有这些都可以使用current()函数在select表达式中实现。
答案 2 :(得分:0)
<xsl:for-each select="/dsInventory/Room">
<xsl:for-each select="/dsInventory/Method">
<xsl:if test="RoomId=../RoomId"></xsl:if>
</xsl:for-each>
</xsl:for-each>
正如回答此问题的人所指出的那样,您正在尝试将/dsInventory/Method/RoomId
与/dsInventory/RoomId
进行比较,后者在提供的XML文档中不存在。
我试图根据相应房间选择方法 房间。
以下是一个完整的转换,展示了如何执行此操作:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Room">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates mode="grab"
select="/*/Method[RoomId = current()/RoomId]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Method" mode="grab">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="Method | Method/RoomId"/>
</xsl:stylesheet>
将此转换应用于以下XML文档(提供的更改方法名称 - 彼此不同):
<dsInventory>
<Room>
<RoomName>kantoor 1</RoomName>
<RoomId>1376257</RoomId>
</Room>
<Room>
<RoomName>Hal</RoomName>
<RoomId>1376258</RoomId>
</Room>
<Method>
<RoomId>1376257</RoomId>
<Name>test1</Name>
</Method>
<Method>
<RoomId>1376258</RoomId>
<Name>test2</Name>
</Method>
</dsInventory>
生成了想要的,正确的结果(添加到房间的方法和删除了顶部元素的Method
子项):
<dsInventory>
<Room>
<RoomName>kantoor 1</RoomName>
<RoomId>1376257</RoomId>
<Method>
<Name>test1</Name>
</Method>
</Room>
<Room>
<RoomName>Hal</RoomName>
<RoomId>1376258</RoomId>
<Method>
<Name>test2</Name>
</Method>
</Room>
</dsInventory>
<强>解释强>:
identity rule 副本&#34; as-is&#34;选择执行它的每个节点。
覆盖身份模板的模板与Room
匹配。这里Room
元素是&#34;浅层复制,模板应用于它的子节点(为它们选择身份模板,并将它们复制到#34;原样&#34;到输出)和然后模板应用于任何Method
,其RoomId
子项与当前匹配的RoomId
子项具有相同的值( current()
){ {1}}元素。因为我们以后想要删除任何Room
元素,所以我们在此指定所需处理(与删除不同)将在Method
模式下完成。
覆盖身份模板的第二个模板会删除所有"grab"
个元素,只需简单匹配它们并拥有一个空体。
与模式Method
中的Method
匹配的模板只是浅层复制并将模板应用于其子项。在其子级中,"grab"
仅与身份模板匹配,并按原样复制&#34;&#34;。 Name
子项由比标识模板更具体的模板匹配,并且选择前者用于执行。所选择的模板没有正文,有效地删除&#34;删除&#34;输出中匹配的RoomId
。