对于这个答案,我看起来很高很低,并尝试了数百个的排列,但一切都没有效果。
我正在尝试处理第一个<title>
节点的简单XML文档的所有节点EXCEPT。基本上,我正在尝试找到一个xslt指令来完成
<xsl:apply-templates select="/topic/title"/>
这是我的源XML:
<topic>
<title>Name of the Document</title>
<p>Document body</p>
<topic>
<title>First Document Subtopic</title>
<p>Body text for first document subtopic</p>
</topic>
<p>Body text continued for document</p>
<topic>
<title>Second Document Subtopic</title>
<p>Body text for document subtopic</p>
<topic>
<title>First Document Sub-subtopic</title>
<p>Body text for first document sub-subtopic</p>
</topic>
</topic>
<p>Body text continued a second time for document</p>
</topic>
这是我的XSLT(我原来想到的应该在调用apply-templates时起作用):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output omit-xml-declaration="yes" encoding="UTF-8" method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<BOX>
<TEXTFLOW>
<xsl:apply-templates select="*[not(/topic/title)]"/>
</TEXTFLOW>
</BOX>
</xsl:template>
<xsl:template match="topic">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="title">
<PARA STYLE="Title"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="p">
<PARA STYLE="BodyText"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()">
<FORMAT>
<xsl:value-of select="."/>
</FORMAT>
</xsl:template>
</xsl:stylesheet>
这是我想要看到的内容(请注意第一个<title>
没有问题):
<BOX>
<TEXTFLOW>
<PARA STYLE="BodyText"/>
<FORMAT>Document body</FORMAT>
<PARA STYLE="Title"/>
<FORMAT>First Document Subtopic</FORMAT>
<PARA STYLE="BodyText"/>
<FORMAT>Body text for first document subtopic</FORMAT>
<PARA STYLE="BodyText"/>
<FORMAT>Body text continued for document</FORMAT>
<PARA STYLE="Title"/>
<FORMAT>Second Document Subtopic</FORMAT>
<PARA STYLE="BodyText"/>
<FORMAT>Body text for document subtopic</FORMAT>
<PARA STYLE="Title"/>
<FORMAT>First Document Sub-subtopic</FORMAT>
<PARA STYLE="BodyText"/>
<FORMAT>Body text for first document sub-subtopic</FORMAT>
<PARA STYLE="BodyText"/>
<FORMAT>Body text continued a second time for document</FORMAT>
</TEXTFLOW>
</BOX>
我可以用什么选择表达来实现这个目标?
答案 0 :(得分:6)
这么简单:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<BOX>
<TEXTFLOW>
<xsl:apply-templates/>
</TEXTFLOW>
</BOX>
</xsl:template>
<xsl:template match="/topic/title"/>
<xsl:template match="title">
<PARA STYLE="Title"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="p">
<PARA STYLE="BodyText"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()">
<FORMAT>
<xsl:value-of select="."/>
</FORMAT>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<topic>
<title>Name of the Document</title>
<p>Document body</p>
<topic>
<title>First Document Subtopic</title>
<p>Body text for first document subtopic</p>
</topic>
<p>Body text continued for document</p>
<topic>
<title>Second Document Subtopic</title>
<p>Body text for document subtopic</p>
<topic>
<title>First Document Sub-subtopic</title>
<p>Body text for first document sub-subtopic</p>
</topic>
</topic>
<p>Body text continued a second time for document</p>
</topic>
产生了想要的正确结果:
<BOX>
<TEXTFLOW>
<PARA STYLE="BodyText"/>
<FORMAT>Document body</FORMAT>
<PARA STYLE="Title"/>
<FORMAT>First Document Subtopic</FORMAT>
<PARA STYLE="BodyText"/>
<FORMAT>Body text for first document subtopic</FORMAT>
<PARA STYLE="BodyText"/>
<FORMAT>Body text continued for document</FORMAT>
<PARA STYLE="Title"/>
<FORMAT>Second Document Subtopic</FORMAT>
<PARA STYLE="BodyText"/>
<FORMAT>Body text for document subtopic</FORMAT>
<PARA STYLE="Title"/>
<FORMAT>First Document Sub-subtopic</FORMAT>
<PARA STYLE="BodyText"/>
<FORMAT>Body text for first document sub-subtopic</FORMAT>
<PARA STYLE="BodyText"/>
<FORMAT>Body text continued a second time for document</FORMAT>
</TEXTFLOW>
</BOX>
<强>解释强>:
要从处理中排除所需元素,我们使用与它们匹配且没有正文的模板:
<xsl:template match="/topic/title"/>
<强> II。更新强>
不推荐以下替代解决方案,因为它是“拉式”的例子,并不像上面的“推式”解决方案那样灵活,优雅和可维护,但是OP坚持认为他需要这样低劣的解决方案:< / p>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<BOX>
<TEXTFLOW>
<xsl:apply-templates
select="*/*[not(self::title)]"/>
</TEXTFLOW>
</BOX>
</xsl:template>
<xsl:template match="title">
<PARA STYLE="Title"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="p">
<PARA STYLE="BodyText"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()">
<FORMAT>
<xsl:value-of select="."/>
</FORMAT>
</xsl:template>
</xsl:stylesheet>
当对提供的XML文档(上面)应用此转换时,它会再次生成所需的正确结果。
答案 1 :(得分:3)
好吧,您可以在根模板中使用此XPath:
select=".//*[generate-id() != generate-id(/topic/title)]"
您需要将topic
的模板更改为:
<xsl:template match="topic" />
您遇到的问题是因为您当前的选择仅指定应处理的直接子项 - 从根音符/
),这实际上只是顶级topic
元素。上面XPath中的.//*
指定所有后代而不管级别,谓词明确排除第一个/topic/title
元素。
您需要确保您的topic
元素不处理他们的孩子,因为他们的孩子已经被根模板中的select指令处理了。