我是XSLT的新手,但需要將其用於目前使用的CMS。我已經提出了一個問題,但我會嘗試描述它,而不會涉及底層CMS的太多信息。如果你需要更多的上下文來幫助我,我可以添加它。XSL:如何測試當前節點是否是另一個節點的後代
所以我想要做的就是測試如果我的XML的節點是特定節點的後代。
<xsl:if test="$currentNode::IsADescendantOf($someNode)">
Write this out.
</xsl:if>
任何想法的人?
感謝提前:)
我是XSLT的新手,但需要將其用於目前使用的CMS。我已經提出了一個問題,但我會嘗試描述它,而不會涉及底層CMS的太多信息。如果你需要更多的上下文來幫助我,我可以添加它。XSL:如何測試當前節點是否是另一個節點的後代
所以我想要做的就是測試如果我的XML的節點是特定節點的後代。
<xsl:if test="$currentNode::IsADescendantOf($someNode)">
Write this out.
</xsl:if>
任何想法的人?
感謝提前:)
您應該使用UNION操作和節點集的大小比較:
<xsl:if test="count($someNode|$currentNode/ancestor::*) = count($currentNode/ancestor::*)">
Write this out.
</xsl:if>
如果$ someNode是$ currentNode的祖先,$ someNode | $ currentNode /祖先:: *將返回與$ currentNode/ancestor :: *相同的節點集(node-set沒有任何雙重)。
如果不是,由於聯合,第一個節點集將比第二個節點集多一個節點。
查看 「祖先」 軸在XSL/XPath的參考
<xsl:if test="ancestor::*[. is $somenode]">
編輯:我跟你一起學習。看看這工作(我希望我有這個系統上可用我的XSL調試器:-)
@Jim Garrison:感謝您的快速回復。這似乎是合理的,但我得到這個錯誤: System.Xml.Xsl.XslLoadException:期望一個節點測試,找到'$'。 – 2009-12-11 06:28:07
你說得對,我的解決方案不完整。我沒有使用XSL ref,但基本思想是您需要使用祖先軸來選擇所有的祖先節點,然後根據節點相等性將其過濾爲$ somenode。 – 2009-12-11 06:32:29
非常感謝。現在我得到「is-same-node()'是一個未知的XSLT函數」我會繼續討論它,但是讓我知道你是否有任何其他想法。 – 2009-12-11 06:42:09
後代檢查
,最好的辦法是使用後代:: *軸。
如果您有一段XML看起來像這樣並且想要匹配來自第一個<alpha>
節點的後代<a>
節點。
XML
<root>
<!-- check for descendants of the following alpha node-->
<alpha>
<!-- match the following node-->
<a>...</a>
<b>...</b>
<c>...</c>
</alpha>
<alpha>
<a>...</a>
<c>...</c>
</alpha>
</root>
XSLT
<xsl:if test="/root/alpha[1]/descendant::a[. is current()]">
祖先檢查
這在大多數情況下,很可能工作。
<xsl:if test="ancestor::*[name() = $node]">
凡
<xsl:variable name="node" select="name(//alpha)"/>
或者你也可以使用產生-ID()如果你有多個節點以比較,需要確保它是一個節點的匹配,而不是名稱匹配。
<xsl:variable name="node" select="generate-id(//alpha[3])"/>
<xsl:if test="ancestor::*[generate-id(.) = $node]">
is
的比較操作者可以比較祖先時,因爲它需要的葉節點不IMO被使用,並且葉節點沒有後代。
但我建議使用descendant :: *軸,因爲它更具可讀性和靈活性。
一種便攜式(XPath 1.0和2.0)的解決辦法是:
<xsl:if test="
$currentNode/ancestor::*[generate-id() = generate-id($someNode)]
">
Write this out.
</xsl:if>
這走到祖先軸,並檢查在它的每一個元件。如果(且僅當)其中一個祖先的唯一ID與唯一ID爲$someNode
匹配,則生成的節點集不爲空。
非空節點集計算爲true,所以條件滿足。
測試 - 找到所有<baz>
這是<foo>
後裔:
<xml>
<foo>
<bar>
<baz>Test 1</baz>
</bar>
</foo>
<baz>Test 2</baz>
</xml>
和
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="/">
<xsl:variable name="someNode" select="//foo[1]" />
<!-- test each <baz> node if it has <foo> as a parent -->
<xsl:for-each select="//baz">
<xsl:if test="
ancestor::*[generate-id() = generate-id($someNode)]
">
<xsl:copy-of select="." />
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
結果
<baz>Test 1</baz>
注意,如果你指的是實際 CURREN t節點,就像我在for-each中那樣,不需要單獨的$currentNode
變量。默認情況下,所有XPath都與當前節點相關。
變體將是自上而下的方式。這是低效率的,但(可能是由幾個數量級):
<xsl:if test="
$someNode[//*[generate-id() = generate-id($currentNode)]]
">
Write this out.
</xsl:if>
答案很簡單,
所有你需要做的是:
<xsl:if test="count(ancestor::somenode)>0">
.. 。然後添加其餘的
的邏輯是,如果節點是somenode的後代,那麼它將有一個或多個該節點。
@Erlock:非常感謝您的幫助。工作過一種享受。 – 2009-12-13 23:38:48