2

我的任务是我必须显示所有节点标签,在显示之前我需要检查 /Datum/DCR/Global/* 中是否存在这些节点/标签,如果存在,那么我想显示来自全局元素的值孩子,否则我想从我的示例节点/标签中的节点元素标签显示“home”在全局元素子节点中不存在,所以我将从 /Result/site-map/segment/node[1]/label 显示和“库存”位于全局元素子节点中,因此我需要显示来自 /Datum/DCR/Global/Inventory 的库存。

XML 文件:-

<Properties>
    <Data>
        <Datum ID="D01" Type="DCR" Name="Global">
            <DCR Category="BAT" Type="global">
                <Global>
                    <FindaDealer>Find a Dealer</FindaDealer> 
                    <Tools>Tools</Tools> 
                    <Inventory>Inventory</Inventory> 
                    <ContactDealers>Contact Dealers</ContactDealers> 
                 </Global>
            </DCR>
        </Datum>
        <Result>
            <site-map id="hnh1clwg" >
                <segment id="0" >
                    <node id="hnhi" >
                        <label key="">home</label> 
                    </node>
                    <node id="hn4h">
                      <label key="">Offers</label>
                    </node>
                    <node id="hn4l">
                      <label key="">Tools</label>
                    </node>
                    <node id="hn62">
                      <label key="">Inventory</label>
                    </node>
                  </segment>
              </site-map>
        </Result>
    </Data>
</properties>

XSL 代码:-

<xsl:element name="ul">
        <xsl:for-each select="Properties/Data/Result/site-map/segment/node">
            <li>
                <a href="#"> 
                    <xsl:apply-templates select="/Properties/Data/Datum[@Name='Global']/DCR/Global/*">
                        <xsl:with-param name="nodelabel" select="label"/>
                    </xsl:apply-templates>          
                </a>
            </li>                                   
        </xsl:for-each>
    </xsl:element>          

<xsl:template name="Glossary" match="/Properties/Data/Datum[@Name='Global']/DCR/Global/*">
    <xsl:param name="nodelabel"/>
    <xsl:variable name="name" select="name(.)"/>
    <xsl:variable name="value" select="."/>

    <xsl:if test="($nodelabel = $value)">
        <xsl:text>From Global element : </xsl:text>                                             
    </xsl:if>
    <xsl:if test="not($nodelabel = $value) and position()=last()">
        <xsl:text>From Sitemap : </xsl:text>                                                
    </xsl:if>

</xsl:template>

我得到的输出: -

From Sitemap : 
From Sitemap : 
From Global element : From Sitemap : 
From Global element : From Sitemap : 

所需的输出: -

From Sitemap : 
From Sitemap : 
From Global element : 
From Global element :

任何指针都会有所帮助。

谢谢

4

1 回答 1

1

我不确定我是否真的理解您在此片段中的逻辑,似乎没有必要将模板应用于每个站点地图节点的所有Global/*元素。您可以在全局值上定义一个,让您按值查找这些节点

<xsl:key name="globalValues" match="Global/*" use="." />

现在您可以为节点定义两个不同的模板,一个匹配在全局列表中有对应节点的节点,另一个匹配没有节点:

<xsl:template match="node[key('globalValues', label)]" priority="10">
  <xsl:text>From Global element : </xsl:text>
  <!-- within this template you can use
         key('globalValues', label)
       to access the corresponding Global/* element -->
</xsl:template>

<xsl:template match="node" priority="5">
  <xsl:text>From Sitemap : </xsl:text>
</xsl:template>

(在这种情况下,明确的优先级并不是绝对必要的,因为默认优先级会做正确的事情,但我认为它们使意图更清晰)。现在有了这些,您只需将模板应用于所有节点元素,模板匹配器将为每个节点选择合适的:

<xsl:element name="ul">
    <xsl:for-each select="Properties/Data/Result/site-map/segment/node">
        <li>
            <a href="#"> 
                <xsl:apply-templates select="." />
            </a>
        </li>                                   
    </xsl:for-each>
</xsl:element>

或更惯用的方式,将<li>and<a>移到目标模板中并摆脱for-each, 只是

<xsl:apply-templates select="Properties/Data/Result/site-map/segment/node" />
于 2013-11-07T18:38:53.770 回答