根据属性将元素分组到新元素
Grouping of elements to new element based on attribute
我需要将没有属性的元素分组到一个新元素中。取决于属性@single h2 是否应该放置在新容器中,或者在没有@single 的情况下与h2s 按顺序放置在一起。我正在为文本 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>
一种可能的 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')])]">
匹配所有没有 @single
属性且值为 true
并且没有第一个前面的兄弟 h2
没有 @single='true'
的所有 h2
。此模板将匹配的 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
模式="copy":
<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')]]"/>
匹配已复制到 <containertypeB>
.
中的所有 h2
元素
我需要将没有属性的元素分组到一个新元素中。取决于属性@single h2 是否应该放置在新容器中,或者在没有@single 的情况下与h2s 按顺序放置在一起。我正在为文本 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>
一种可能的 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')])]">
匹配所有没有 @single
属性且值为 true
并且没有第一个前面的兄弟 h2
没有 @single='true'
的所有 h2
。此模板将匹配的 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
模式="copy":
<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')]]"/>
匹配已复制到 <containertypeB>
.
h2
元素