我创建了一个样式表,它应该有选择地复制XML文档的内容,以便我可以删除不需要的数据。我在下面提供了2个示例以及我们当前用来执行此操作的样式表。样式表有效,但我认为可能有更好的方法,因为在当前版本中我在两个不同的位置检查相同的东西(author ='John Doe')。
在输出中包含xml元素的规则如下:
<transaction>
<policy>
<insco>CC</insco>
<notepads>
<notepad>
<author>Andy</author>
<notepad>
<notepad>
<author>John Doe</author>
<notepad>
<notepad>
<author>Barney</author>
<notepad>
</notepads>
</policy>
</transaction>
<transaction>
<policy>
<insco>CC</insco>
<notepads>
<notepad>
<author>John Doe</author>
<notepad>
</notepads>
</policy>
</transaction>
<transaction>
<policy>
<insco>CC</insco>
<notepads>
<notepad>
<author>Andy</author>
<notepad>
</notepads>
</policy>
</transaction>
<transaction>
<policy>
<insco>CC</insco>
</policy>
</transaction>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn">
<xsl:template match="*">
<xsl:choose>
<xsl:when test="name()='notepads'">
<xsl:if test="/transaction/policy/insco='CC' and (notepad/author='John Doe')">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:if>
</xsl:when>
<xsl:when test="name()='notepad'">
<xsl:if test="author='John Doe'">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:2)
使用模板,它们通常更有效,并且避免name()
检查,它们是缓慢且不可靠的(前缀和名称空间不适合这些):
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="notepads">
<xsl:if test="(ancestor::policy/insco='CC') and (notepad/author='John Doe')">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="notepad">
<xsl:if test="author='John Doe'">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:2)
我可以想到两种方法来做到这一点。
1)身份模板,硬编码作者姓名:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<!-- nodepads generally get removed... -->
<xsl:template match="notepad" />
<!-- ...unless their author is 'Jon Doe' -->
<xsl:template match="notepad[author='John Doe']">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
2)修改了身份模板,XSL密钥,参数化作者姓名:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:param name="theAuthor" select="'John Doe'" />
<xsl:key
name="kNotepad" match="notepad[author]"
use="concat(generate-id(..), '|', author)"
/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="
node()[not(self::notepad)]
|key('kNotepad', concat(generate-id(), '|', $theAuthor))
|@*"
/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
第二种方法需要一点解释:
<xsl:key>
为所有<nodepad>
个节点编制索引,这些节点的父级唯一ID和作者姓名为<author>
<notepads>
的唯一ID是'id0815'
,那么您感兴趣的<notepad>
的关键是'id0815|Jon Doe'
<notepad>
的节点:node()[not(self::notepad)]
@*
key()
的调用自然只会在<notepads>
个元素上返回任何内容(因为它包含他们的唯一ID)<notepads>
元素(在我们的情况下为'id0815'
)时,key()
将仅返回其'Jon Doe'
个子元素,在所有其他情况下,它将返回转空