使用此源文檔:問題使用祖先軸在XPath謂詞
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Element1 id="UniqueId1">
<SubElement1/>
<SubElement2>
<LeafElement1/>
<LeafElement1/>
</SubElement2>
</Element1>
<Element2 id="UniqueId2" AttributeToCheck="true">
<SubElement1>
<LeafElement1/>
<LeafElement1/>
</SubElement1>
</Element2>
</Root>
欲屬性富=「欄中的」添加到該兩個元件:
- 具有與同級元素同名
- 有任何祖先屬性AttributeToCheck
這應該是RESU lt:
<?xml version="1.0"?>
<Root>
<Element1 id="UniqueId1">
<SubElement1/>
<SubElement2>
<LeafElement1/>
<LeafElement1/>
</SubElement2>
</Element1>
<Element2 id="UniqueId2" AttributeToCheck="true">
<SubElement1>
<LeafElement1 foo="bar"/>
<LeafElement1 foo="bar"/>
</SubElement1>
</Element2>
</Root>
這是我的表單到目前爲止。它增加了匹配條件1的屬性的元素,但無法說清條件2
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="* | @*">
<xsl:copy>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[count(../*[name(.) = name(current())]) > 1]">
<xsl:copy>
<xsl:attribute name="foo">bar</xsl:attribute>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
不正確的輸出:
<?xml version="1.0"?>
<Root>
<Element1 id="UniqueId1">
<SubElement1/>
<SubElement2>
<LeafElement1 foo="bar"/> (incorrect)
<LeafElement1 foo="bar"/> (incorrect)
</SubElement2>
</Element1>
<Element2 id="UniqueId2" AttributeToCheck="true">
<SubElement1>
<LeafElement1 foo="bar"/> (correct)
<LeafElement1 foo="bar"/> (correct)
</SubElement1>
</Element2>
</Root>
由於第二模板已經正確地匹配具有相同名稱的兄弟姐妹元素,應該很容易使用祖先XPath軸來排除沒有AttributeToCheck祖先的元素。我在第二個模板中添加了另一個謂詞。
<xsl:template match="*[ancestor::*[@AttributeToCheck]][count(../*[name(.) = name(current())]) > 1]">
當我應用此樣式表時,輸出文檔與輸入文檔相同,表明第二個模板與任何元素都不匹配。我也嘗試改變新的謂詞來使用節點數。
<xsl:template match="*[count(ancestor::*[@AttributeToCheck]) > 0][count(../*[name(.) = name(current())]) > 1]">
這也行不通,輸出文件與輸入文件相同。這是令人驚訝的,因爲當我使用這個祖先表達式來輸出具有AttributeToCheck的節點名稱時,它就可以工作。我做了這些改動sylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="* | @*">
<xsl:copy>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[count(../*[name(.) = name(current())]) > 1]">
<xsl:copy>
<xsl:attribute name="foo">bar</xsl:attribute>
<xsl:attribute name="AncestorCount">
<xsl:value-of select="count(ancestor::*[@AttributeToCheck])"/>
</xsl:attribute>
<xsl:attribute name="AncestorName">
<xsl:value-of select="name(ancestor::*[@AttributeToCheck])"/>
</xsl:attribute>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
產生這樣的輸出:
<?xml version="1.0"?>
<Root>
<Element1 id="UniqueId1">
<SubElement1/>
<SubElement2>
<LeafElement1 foo="bar" AncestorCount="0" AncestorName=""/>
<LeafElement1 foo="bar" AncestorCount="0" AncestorName=""/>
</SubElement2>
</Element1>
<Element2 id="UniqueId2" AttributeToCheck="true">
<SubElement1>
<LeafElement1 foo="bar" AncestorCount="1" AncestorName="Element2"/>
<LeafElement1 foo="bar" AncestorCount="1" AncestorName="Element2"/>
</SubElement1>
</Element2>
</Root>
我的問題是,爲什麼XPath的謂詞*[ancestor::*[@AttributeToCheck]][count(../*[name(.) = name(current())]) > 1]
不正確匹配匹配兩個條件1和2的元素?我應該使用什麼XPath表達式?
您使用的是哪種XSL庫? .NET XSL庫無法在模式內處理'current()',並且(一旦我得到了補償),* [ancestor :: * [@ AttributeToCheck]] [count(../* [name(。)= name(current())])> 1]'表達式按預期工作。我認爲你的XSL庫已經搞亂了。 – Welbog 2009-11-30 15:29:08
它也適用於W3Cchool的try it編輯器:http://www.w3schools.com/Xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog – Welbog 2009-11-30 15:39:10
我使用的是XmlStarlet 1.0.1,我認爲它是當前的版本。 XmlStarlet使用libxml2-2.7.6和libxslt-1.1.26。 – Chris 2009-11-30 16:25:46