我需要将没有属性的元素分组到一个新元素中。取决于属性@single h2应该放在新容器中,还是与h2s按顺序分组而没有@single的位置。我正在与小组争论2,3,4。我是否需要为h1创建一个模板,然后我们为xsl:for-each创建一个模板?有更聪明的方法吗?
来源:
<h1>
<h2 single="true" />
<h2 single="true" />
<h2>1</h2>
<h2 single="true" />
<h2>2</h2>
<h2>3</h2>
<h2>4</h2>
<h2 single="true" />
<h2>5</h2>
</h1>
结果
<h1>
<containertypeA>
<h2 single="true" />
</containertypeA>
<containertypeA>
<h2 single="true" />
</containertypeA>
<containertypeB>
<h2>1</h2>
</containertypeB>
<containertypeA>
<h2 single="true" />
</containertypeA>
<containertypeB>
<h2>2</h2>
<h2>3</h2>
<h2>4</h2>
</containertypeB>
<containertypeA>
<h2 single="true" />
</containertypeA>
<containertypeB>
<h2>5</h2>
</containertypeB>
</h1>
答案 0 :(得分:0)
一种可能的XSLT 1.0解决方案是遵循XSLT:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8"
indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="h2[@single='true']">
<containertypeA>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</containertypeA>
</xsl:template>
<xsl:template match="h2[not(@single='true') and
not(preceding-sibling::h2[1][not(@single='true')])]">
<containertypeB>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:for-each select="following-sibling::h2[1][not(@single='true')]">
<xsl:apply-templates select="." mode="sibling"/>
</xsl:for-each>
</containertypeB>
</xsl:template>
<xsl:template match="h2" mode="sibling">
<xsl:apply-templates select="." mode="copy"/>
<xsl:for-each select="following-sibling::h2[1][not(@single='true')]">
<xsl:apply-templates select="." mode="sibling"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="h2[not(@single='true') and
preceding-sibling::h2[1][not(@single='true')]]" mode="copy">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="h2[not(@single='true') and
preceding-sibling::h2[1][not(@single='true')]]"/>
</xsl:transform>
当应用于输入XML时产生输出
<h1>
<containertypeA>
<h2 single="true"/>
</containertypeA>
<containertypeA>
<h2 single="true"/>
</containertypeA>
<containertypeB>
<h2>1</h2>
</containertypeB>
<containertypeA>
<h2 single="true"/>
</containertypeA>
<containertypeB>
<h2>2</h2>
<h2>3</h2>
<h2>4</h2>
</containertypeB>
<containertypeA>
<h2 single="true"/>
</containertypeA>
<containertypeB>
<h2>5</h2>
</containertypeB>
</h1>
模板
<xsl:template match="h2[@single='true']">
在h2
中复制每个匹配的<containertypeA>
模板
<xsl:template match="h2[not(@single='true') and
not(preceding-sibling::h2[1][not(@single='true')])]">
将没有h2
属性且价值为@single
的所有true
与没有h2
的前一个兄弟@single='true'
匹配。此模板将匹配的h2
包含在<containertypeB>
中,并将template mode="sibling"
应用于以下第一个没有@single='true'
的兄弟:
<xsl:for-each select="following-sibling::h2[1][not(@single='true')]">
<xsl:apply-templates select="." mode="sibling"/>
<xsl:template match="h2" mode="sibling">
使用模板复制h2
模式=&#34;复制&#34;:
<xsl:apply-templates select="." mode="copy"/>
并适用于所有以下没有@single='true'
的第一个兄弟姐妹:
<xsl:for-each select="following-sibling::h2[1][not(@single='true')]">
<xsl:apply-templates select="." mode="sibling"/>
</xsl:for-each>
最后,空模板
<xsl:template match="h2[not(@single='true') and
preceding-sibling::h2[1][not(@single='true')]]"/>
匹配已复制到h2
的所有<containertypeB>
元素。