我有一个XML文件,类似于:
<doc>
<element>
<word>
<text>one word</text>
</word>
<word>
<text>two words</text>
</word>
</element>
<element>
<other>
<text>the sky</text>
</other>
<word>
<text>NN NN</text>
</word>
</element>
</doc>
我希望只有一个标签和行的内容,当有两个接一个接一个时,就像那样:
<element>
<word>
<text>one word</text>
<text>two words</text>
</word>
</element>
问题在于我正在生成<xsl:element>
以获取<word>
标记。此<xsl:element>
已经在<xsl:for-each>
循环中,可以使<word>
代码按正确顺序排列(过滤属性)。
我以前的XML文档是这样的:
<doc>
<element class="word">
<text>one word</text>
</element>
<element class="word">
<text>NN NN</text>
</element>
<element class="word">
<text>two words</text>
</element>
<element class="other">
<text>the sky</text>
</element>
</doc>
任何帮助都会很棒,谢谢:)
- 更多详情 -
这是我想要的结果:
<doc>
<element>
<word>
<text>one word</text>
<text>two words</text>
</word>
</element>
<element>
<other>
<text>the sky</text>
</other>
<word>
<text>NN NN</text>
</word>
</element>
</doc>
我无法指定标记字或其他,因为我没有关闭的标记列表。所以我使用 xsl:variable :
<xsl:for-each select="element">
<xsl:variable name="name">
<xsl:value-of select="@class"/>
</xsl:variable>
<xsl:element name="{$name}">
<text>
<xsl:value-of select="."/>
</text>
</xsl:element>
</xsl:for-each>
答案 0 :(得分:1)
试试这个:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="element/*">
<xsl:if test="not(preceding-sibling::*[name() = name(current())])">
<xsl:copy>
<xsl:apply-templates select="* | following-sibling::*[name()=name(current())]/*" />
</xsl:copy>
</xsl:if>
</xsl:template>
<!-- Identity template -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
它只是查找element
的任何没有同名兄弟的子节点(即每个节点的第一个),然后将模板应用于它自己的子节点和子节点任何以下同名兄弟姐妹。
答案 1 :(得分:0)
您只需使用<xsl:apply-templates/>
...
XML输入
<doc>
<element>
<word>
<text>one word</text>
</word>
<word>
<text>two words</text>
</word>
</element>
<element>
<other>
<text>the sky</text>
</other>
<word>
<text>NN NN</text>
</word>
</element>
</doc>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="element">
<xsl:copy>
<word>
<xsl:apply-templates/>
</word>
</xsl:copy>
</xsl:template>
<xsl:template match="word|other">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
<强>输出强>
<doc>
<element>
<word>
<text>one word</text>
<text>two words</text>
</word>
</element>
<element>
<word>
<text>the sky</text>
<text>NN NN</text>
</word>
</element>
</doc>
答案 2 :(得分:0)
此转化:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="element/*"/>
<xsl:template match="element/*[1]">
<word>
<xsl:apply-templates select="../*/*"/>
</word>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<doc>
<element>
<word>
<text>one word</text>
</word>
<word>
<text>two words</text>
</word>
</element>
<element>
<other>
<text>the sky</text>
</other>
<word>
<text>NN NN</text>
</word>
</element>
</doc>
产生(我猜的是)想要的正确结果:
<doc>
<element>
<word>
<text>one word</text>
<text>two words</text>
</word>
</element>
<element>
<word>
<text>the sky</text>
<text>NN NN</text>
</word>
</element>
</doc>