這是XPath的,XML和XSLT的最常見問題。搜索「默認命名空間和XPath表達式」。
作爲用於溶液:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://india.com/states">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="*[not(ancestor-or-self::x:city)]">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
當這個變換所提供的XML文檔施加:
<country xmlns="http://india.com/states" version="1.0">
<state>
<city>
<name>DELHI</name>
</city>
</state>
</country>
有用結果產生:
<city>
<name>DELHI</name>
</city>
說明:
在XPath前綴的元素名稱是始終considerd是在 「沒有命名空間」。但是,所提供的XML文檔中的每個元素名稱都位於非空名稱空間(默認名稱空間"http://india.com/states"
)中。因此,//city
沒有選擇任何節點(因爲XML文檔中沒有元素沒有名稱空間),而//x:city
其中x:
綁定到名稱空間"http://india.com/states"
選擇所有城市元素(位於名稱空間"http://india.com/states"
中)。
在這個轉換中有兩個模板。第一個模板匹配任何元素並重新創建它,但是在無名稱空間中。它還複製所有屬性,然後將模板應用於此元素的子節點。
第二個模板覆蓋了不是city
元素的祖先的所有元素的第一個模板,或者它們自己不是city
元素的第一個模板。此處的操作是在所有子節點上應用模板。
UPDATE:該OP已經修改了問題,問爲什麼在處理一個新的,修改後的XML文檔的結果不想要的文字:
<country xmlns="http://india.com/states" version="1.0">
<state>
<city>
<name>DELHI</name>
</city>
</state>
<state2>
<city2>
<name2>MUMBAI</name2>
</city2>
</state2>
</country>
爲了不到產生文本「MUMBAI」,上面的轉換需要稍微修改 - 忽略(不復制)任何沒有x:city
祖先的文本節點。爲此,我們添加下面一行,空模板:
<xsl:template match="text()[not(ancestor::x:city)]"/>
整個改造現在變成:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://india.com/states">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="*[not(ancestor-or-self::x:city)]">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()[not(ancestor::x:city)]"/>
</xsl:stylesheet>
,結果仍然是有用的,正確的一個:
<city>
<name>DELHI</name>
</city>
問得好,+1。查看我的答案,獲得完整,簡短和簡單的解決方案。還提供了詳細的解釋。 –
我更新了我的答案,修改了「另一個約翰」的問題。如果這是你,請聯繫SO合併你的兩個身份。 –
我的回答對你有用嗎? –