2011-02-01 74 views
17

我正在編寫XSL轉換。我想寫一個模板,它匹配除一個特定節點以外的文檔的所有子元素。我的XML看起來是這樣的 -如何編寫xpath以匹配除特定元素以外的所有元素

<Document> 
    <NodeA></NodeA> 

    <NodeB></NodeB> 

    <ServiceNode></ServiceNode> 

    <NodeX></NodeX> 
</Document> 

我想寫一個匹配除ServiceNodeNodeANodeX所有節點的模板。如何寫這個XPath來獲得 -

<xsl:template match="ALL Nodex Except ServiceNode"> 
+0

問得好,+1。對於這個問題的四種不同可能的含義,請參閱我的答案以獲得四種替代方案。 – 2011-02-01 13:41:16

回答

26

我想寫一個模板,除了ServiceNode 比賽的所有節點即NodeA上到節點X。

如果「節點」你的意思是元素,那麼使用

<xsl:template match="*[not(self::ServiceNode)]"> 

如果「節點」你的意思是任何一個節點(類型的元素,文本,註釋,處理指令) :如果你想只Document孩子要匹配使用使用

<xsl:template match="node()[not(self::ServiceNode)]"> 

<xsl:template match="Document/node()[not(self::ServiceNode)]"> 

如果你只想要頂件的孩子要匹配使用:

<xsl:template match="/*/node()[not(self::ServiceNode)]"> 
2
<xsl:template match="Document/*[name() != 'ServiceNode']"> 

(或local-name(),如果你要處理的命名空間)

+0

我建議在像http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm這樣的實時評估器中進行測試,您可以在其中粘貼表達式,如// * [name()!=「pet」] – 2011-02-01 07:26:32

+0

非常錯誤傾向... – 2011-02-01 16:54:18

0
/Document/*[not(name()='ServiceNode')] 
4

你應該更好地使用這個表達式:

*[not(self::ServiceNode)] 

包含在XSLT中:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 

    <xsl:template match="/*"> 
     <xsl:apply-templates select="*[not(self::ServiceNode)]"/> 
    </xsl:template> 

    <xsl:template match="*"> 
     <xsl:value-of select="."/> 
     <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 

有了這個XML示例:

<Document> 
    <NodeA>1</NodeA> 
    <NodeB>2</NodeB> 
    <ServiceNode>3</ServiceNode> 
    <NodeX>4</NodeX> 
</Document> 

它會給出正確的結果:

1 
2 
4 
+4

正確。這比在name()或local-name()上測試更好。在XPath 2中。0替代方案是(* ServiceNode除外) – 2011-02-01 09:41:42

1

你可以使用兩個模板:

<xsl:template match="Document/*"> 
    ...do something... 
</xsl:template> 


<xsl:template match="Document/ServiceNode" /> 

後來的模板將優先,所以第一個模板將匹配除ServiceNode以外的所有內容。

相關問題