2012-01-13 41 views
2

再次介紹節點集中的不同節點(基於屬性值)。 想象u有以下結構:跨XSLT節點集的不同值

<struct> 
    <a> 
    <x id="1">a_1</x> 
    <x id="2">a_2</x> 
    <x id="3">a_3</x> 
    </a> 
    <b inherits="a"> 
    <x id="2">b_2</x> 
    </b> 
</struct> 

<struct/>可以包含多個元素,比如<b/>其繼承相同<a/>。同時允許多個元素,如<a/>。訂單<a/> s和<b/> s是任意的。繼承是單層次的。

問題:如何創建一個的XPath,用於選擇一個給定的<b/>以下節點集:

<x id="1">a_1</x> 
<x id="2">b_2</x> 
<x id="3">a_3</x> 

請注意在第二行的b_2值。

對此的任何解決方案?

更新:

的resuting的XPath應具有以下形式:b[(magic_xpath)[@id=2]='b_2'],其中magic_xpath<a/> S和<b/> S選用不同<x/>秒。

現實生活<struct/>可以是這樣的:

<struct> 
    <a> 
    <x id="1">a_1</x> 
    <x id="2">a_2</x> 
    <x id="3">a_3</x> 
    </a> 
    <b inherits="a"> 
    <x id="2">I don't match resulting XPath</x> 
    </b> 
    <b inherits="a"> 
    <x id="2">b_2</x> 
    </b> 
</struct> 
+0

更新的含義是不明確的。當更新中的所有'x'元素都有不同的值時,結果是什麼以及爲什麼需要「不同的'?請更新更新以使其清晰明確 – 2012-01-14 04:17:03

回答

1

使用

$vB/x 
| 
    /*/*[name() = $vB/@inherits] 
       /x[not(@id = $vB/x/@id)] 

其中$vB被定義爲b元素。

這將選擇所有b/x元素的聯合和所有x兒童(與id屬性,該屬性是不等於任何b/x/@id屬性)struct/*元件(的struct兒童),其名稱是的b/@inherits值。

或者,如評論請求由OP - 不變量:

/*/b/x 
| 
    /*/*[name() = /*/b/@inherits] 
       /x[not(@id = /*/b/x/@id)] 

完整的基於XSLT的驗證

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "/*/b/x 
    | 
     /*/*[name() = /*/b/@inherits] 
        /x[not(@id = /*/b/x/@id)] 

    "/> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉變是所提供的應用(糾正爲格式良好)XML文檔

<struct> 
    <a> 
     <x id="1">a_1</x> 
     <x id="2">a_2</x> 
     <x id="3">a_3</x> 
    </a> 
    <b inherits="a"> 
     <x id="2">b_2</x> 
    </b> 
</struct> 

單XPath表達式求值和所選擇的節點輸出

<x id="1">a_1</x> 
<x id="3">a_3</x> 
<x id="2">b_2</x> 
+0

謝謝你這麼快速的回答!但是,是否有可能做同樣的事情_without_聲明變量? – 2012-01-13 14:27:06

+0

是的,只需用'/ */b'替換'$ vB' – 2012-01-13 14:29:02

+0

@Savva Mikhalevski:我編輯了一個XPath表達式的答案,該表達式沒有引用變量 – 2012-01-13 14:31:50