2015-01-15 56 views
2

我有一個節點集,我想使用謂詞來從中選擇只有那些以模板當前節點爲父節點的節點。XPath謂詞「是當前節點的父類?」

我使用的是XSL 1.0和msxsl。

在下面的非工作代碼,謂詞[父::電流()]不工作,我希望它爲當前()不是一個有效的NodeTest:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" /> 

    <xsl:variable name="set" select="//node[@attr1 = 'bbb']"/> 

    <xsl:template name="TemplateA"> 
     <xsl:for-each select="$set[parent::current()]"> 
      <result-node> 
       <xsl:value-of select="@value"/> 
       <xsl:text>A</xsl:text> 
      </result-node> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template name="TemplateB"> 
     <xsl:for-each select="$set[parent::current()]"> 
      <result-node> 
       <xsl:value-of select="@value"/> 
       <xsl:text>B</xsl:text> 
      </result-node> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="/body"> 
     <result> 
     <xsl:for-each select="parentNode"> 
      <xsl:call-template name="TemplateA" /> 
      <xsl:call-template name="TemplateB" /> 
     </xsl:for-each> 
     </result> 
    </xsl:template> 

</xsl:transform> 

這裏是一個示例XML喂以上:

<?xml version="1.0" encoding="UTF-8"?> 
<body> 
    <parentNode> 
     <node attr1="aaa" value="1" /> 
     <node attr1="bbb" value="2" /> 
    </parentNode> 

    <parentNode> 
     <node attr1="aaa" value="3" /> 
     <node attr1="bbb" value="4" /> 
    </parentNode> 
</body> 

這裏是所期望的輸出:

<result> 
    <result-node>2A</result-node> 
    <result-node>2B</result-node> 
    <result-node>4A</result-node> 
    <result-node>4B</result-node> 
</result> 

上面的例子可以也可以在這裏找到:http://xsltransform.net/jyH9rMg

+0

一個完整的,可回答的問題!但是,再次調用命名模板可能不是必需的 - 具體取決於實際代碼的範圍。另外,請注意代碼中有'version =「2.0」',您應該將其更改爲'version =「1.0」'。 –

+0

Servus Mathias。按照建議更正。我的實際代碼非常複雜,所以我爲SO提供了一個簡化的例子。我在示例中使用了與真實代碼中相同的技巧,以避免無意中提出錯誤的問題。但是,這說,如果你有一個更好的方式來做同樣的事情,我(和其他人)可能可以從中學習。如果您覺得受到啓發,請將其添加到xsltransform.net鏈接。 (非常感謝您向我展示xsltransform.net!) –

+1

然後,這非常好 - 如果您在發佈代碼之前已經大幅縮減了代碼,那麼這是正確的做法。然後我相信你有很好的理由來命名模板。是的,這個xsltransform網站非常棒。 –

回答

3

在XSLT 1.0比較身份節點的方法是使用generate-id()

<xsl:for-each select="$set[generate-id(..) = generate-id(current())]"> 

..parent::node()的簡寫,是指上下文節點的父(節點正在通過執行謂詞來測試)。

+1

@CaptainNormal關於你建議的編輯:'..'和'parent :: *'一樣有效 - 實際上,這種簡寫的方式有時候會派上用場。所以,我不希望你編輯它。你可以讓伊恩編輯他的答案,並且包括一個簡短的「..」。 –

+1

完整答案在這裏:http://xsltransform.net/jyH9rMg/5 –

+1

@CaptainNormal如果你有機會升級到XSLT 2.0,它會變得更短使用'is'運算符 - '$ set [.. is current( )]' –