I. XSLT 1.0解決方案(這對於XSLT 2.0更容易):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:fileNames>
<f>filename1</f>
<f>filename2</f>
</my:fileNames>
<xsl:variable name="vFilenames"
select="document('')/*/my:fileNames/*"/>
<xsl:template match="node()|@*" name="identity" priority="-1">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()">
<xsl:variable name="vCur" select="."/>
<xsl:variable name="vHit">
<xsl:for-each select="$vFilenames">
<xsl:if test=
"$vCur/node()[contains(@Source, current())]">1</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="not(string-length($vHit))">
<xsl:call-template name="identity"/>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
當這個XML文檔(你什麼時候,人,學習提供源XML ???)施加:
<t>
<tt>
<x>
<y/>
</x>
<mm>
<z Source="filename1">
<u/>
<v/>
</z>
</mm>
<rr>
<m Source="filename2">
<u/>
<v/>
</m>
</rr>
<v-v>
<p Source="filename3">
<u/>
<v/>
</p>
</v-v>
</tt>
</t>
產生想要的,正確的結果:
<t>
<tt>
<x>
<y/>
</x>
<v-v>
<p Source="filename3">
<u/>
<v/>
</p>
</v-v>
</tt>
</t>
二, XSLT 2.0溶液:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pFileNames">
<f>filename1</f>
<f>filename2</f>
</xsl:param>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"node()[node()
[some $fn in $pFileNames/f
satisfies
contains(@Source, $fn)
]
]"/>
</xsl:stylesheet>
當這種轉變是在同一個XML文檔應用(如上述)中,相同的正確的結果產生:
<t>
<tt>
<x>
<y/>
</x>
<v-v>
<p Source="filename3">
<u/>
<v/>
</p>
</v-v>
</tt>
</t>
您沒有示出的XML源,但我想知道你是否真的需要包含()在這裏?我問,因爲使用contains()其中「=」會做是一個常見的錯誤;如果是這樣的話,答案將只是'match =「* [*/@ Source = $ FileName/name]」' – 2012-01-18 09:41:09