2013-05-14 62 views
1

我尝试为每个节点的每个父节点都有问题。我有这样的XML:xsl祖先或自我不返回结果

<item name="news" id="77"> 
    <items> 
    <item id="102" /> 
    <item id="103" />   
    </items> 
</item>  
<item id="86"> 
    <items> 
    <item id="122"> 
     <items> 
     <item id="6" /> 
     <item id="9" /> 
     </items> 
    </item> 
    <item id="12"> 
     <items> 
     <item id="13" /> 
     <item id="18" /> 
     <item id="19" /> 
     </items> 
    </item> 
    </items> 
</item> 
<item name="sitemap" id="88" />  

而且在模板中我尝试这样的:

<xsl:template name="render"> 
<xsl:param name="length" /> 
<xsl:param name="item" /> 
    <xsl:for-each select="ancestor-or-self::item[@id='9']">   
    some code 
    </xsl:for-each>  
<xsl:apply-templates select="*"/> 

请帮助我,如果你能。

UPD:
我希望得到一些像菜单(如果选用带有ID选项= 9):

<ul> 
<li>77</li> 
<li> 
    86 
    <ul> 
    <li> 
    122 
    <ul> 
    <li>6</li> 
    <li>9</li> 
    </ul> 
    </li> 
    <li>12</li> 
    </ul> 
</li> 
<li>88</li> 
</ul> 

我的XSLT(我想想)不好:

<xsl:template match="/"> 
<ul> 
<xsl:call-template name="render"> 
    <xsl:with-param name="item" select="item[@id='9']" /> 
    <xsl:with-param name="length" select="0" /> 
</xsl:call-template> 
</ul> 
</xsl:template> 

<xsl:template name="render"> 
    <xsl:param name="length" /> 
    <xsl:param name="item" /> 
    <xsl:for-each select="$item/ancestor-or-self::item[@id='9']">   
    <xsl:if test="position()=length"> 
     <xsl:variable name="current" select="." /> 
     <xsl:for-each select="../item"> 
     <xsl:choose> 
      <xsl:when test=".=current"> 
      <li class="selectedItem"> 
       <p> 
       <xsl:value-of select="@id"/> 
       </p> 
       <xsl:call-template name="render"> 
       <xsl:with-param name="length" select="$lenght + 1" /> 
       <xsl:with-param name="item" select="$item" /> 
       </xsl:call-template> 
      </li> 
      </xsl:when> 
      <xsl:otherwise> 
      <li> 
       <p> 
       <xsl:value-of select="@id"/> 
       </p> 
      </li> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each> 
    </xsl:if> 
    </xsl:for-each>  
<xsl:apply-templates select="*"/> 
</xsl:template> 
+1

你的问题不是特别清楚,更多的是一个声明,而不是一个问题。你能更具体一些吗?特别是,你正在寻找什么样的输出。 – freefaller 2013-05-14 15:33:01

+0

调用'render'模板时的当前节点是什么?你能向我们展示一些你的XSLT吗? – JLRishe 2013-05-14 16:29:06

回答

1

你还没有明确你的问题,但我不知道你是否正在寻找祖先的参数节点$ item,而不是上下文节点的祖先?如果是这样,这将是

select="$item/ancestor-or-self::item[@id='9'] 

然而,在示例XML,与@ ID =的唯一节点“9”是不是任何事物的祖先,所以我怀疑我在黑暗中摸索。

+0

我编辑我的问题。也许你理解我是正确的。 – LuckSound 2013-05-15 07:14:44

1

所以基本上你想要生成一个树结构,其中所有节点都“折叠”,除了具有指定ID的节点。我想不同的办法是:

<xsl:template match="items | menu" mode="menu"> 
    <xsl:param name="targetId" /> 
    <ul> 
    <xsl:apply-templates select="item" mode="menu"> 
     <xsl:with-param name="targetId" select="$targetId"/> 
    </xsl:apply-templates> 
    </ul> 
</xsl:template> 

<xsl:template match="item" mode="menu"> 
    <xsl:param name="targetId" /> 
    <li> 
    <xsl:if test="@id = $targetId"> 
     <xsl:attribute name="class">selectedItem</xsl:attribute> 
    </xsl:if> 
    <xsl:value-of select="@id"/> 

    <!-- expand the branch only if it contains the target id --> 
    <xsl:apply-templates select="items[.//@id = $targetId]" mode="menu"> 
     <xsl:with-param name="targetId" select="$targetId"/> 
    </xsl:apply-templates> 
    </li> 
</xsl:template> 

而当你想呈现一个特定ID的菜单中,您刚才说

<xsl:apply-templates select="/menu" mode="menu"> 
    <xsl:with-param name="targetId" select="'9'"/> 
</xsl:apply-templates> 

(在这里我假设你原来的XML有一个<menu>根元素包裹围绕item元素的顶级集合,如果不是这种情况,您将不得不调整匹配并适当选择表达式)。

如果要还显示目标ID的水平以下(例如包括6,9层当目标ID是122),则只需改变

<xsl:apply-templates select="items[.//@id = $targetId]" mode="menu"> 

<xsl:apply-templates select="items[current()//@id = $targetId]" mode="menu"> 
0

外表在下面的解决方案

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:variable name="home" select="//item[@name='home']" /> 


<xsl:variable name="current_item" select="//item[@id = '55']" /> 

<xsl:variable name="parents_line" select="$current_item/ancestor-or-self::item" /> 

<xsl:variable name="path"> 
<xsl:for-each select="$parents_line"> 
    <xsl:text>/</xsl:text> 
    <xsl:value-of select="@id"/> 
    <xsl:if test="position()=last()">/</xsl:if> 
</xsl:for-each> 

</xsl:variable> 

<xsl:template match="*"> 
    <xsl:call-template name="menu" /> 
</xsl:template> 

<xsl:template name="menu"> 
    <xsl:param name="level" select="1" /> 
    <xsl:param name="start" select="$home" /> 

    <ul> 
     <xsl:for-each select="$start/items/item"> 
     <xsl:variable name="current_id" select="@id" /> 
     <li> 
      <xsl:value-of select="@name" /> 

      <xsl:if test="contains($path, concat('/', $current_id, '/'))"> 
      <xsl:call-template name="menu"> 
       <xsl:with-param name="level" select="$level+1" /> 
       <xsl:with-param name="start" select="." /> 
      </xsl:call-template> 
      </xsl:if> 
     </li> 
     </xsl:for-each> 
    </ul> 
    </xsl:template> 

</xsl:stylesheet>