如何使用 for-each-group 包裹 XSLT 中的元素? [英] How to WRAP the elements in XSLT using for-each-group?
问题描述
我想使用 XSLT
示例 XML 文档-
<root>
<root1>
<root2>
<value1>somevalue</value1>
<value2>somevalue</value2>
<value3>somevalue</value3>
<value4>somevalue</value4>
<value5>Australia</value5>
<value6>India</value6>
<value7>USA</value7>
<value8>somevalue</value8>
<value9>somevalue</value9>
<value10>somevalue</value10>
</root2>
</root1>
</root>
输出 XML-
<root>
<root1>
<root2>
<value1>somevalue</value1>
<value2>somevalue</value2>
<value3>somevalue</value3>
<value4>somevalue</value4>
<COUNTRY>
<value5>Australia</value5>
<value6>India</value6>
<value7>USA</value7>
</COUNTRY>
<value8>somevalue</value8>
<value9>somevalue</value9>
<value10>somevalue</value10>
</root2>
</root1>
</root>
我目前使用的代码-
xquery version "1.0-ml";
declare variable $doc := document {
<root>
<root1>
<root2>
<value1>somevalue</value1>
<value2>somevalue</value2>
<value3>somevalue</value3>
<value4>somevalue</value4>
<value5>Australia</value5>
<value6>India</value6>
<value7>USA</value7>
<value8>somevalue</value8>
<value9>somevalue</value9>
<value10>somevalue</value10>
</root2>
</root1>
</root>
};
declare variable $grouping-xslt := <xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="not(self::value5 | self::value6 | self::value7)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:copy-of select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<country>
<xsl:copy-of select="current-group()"/>
</country>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>;
xdmp:xslt-eval($grouping-xslt, $doc)
我在形成关于 root
的模板时遇到了一些问题.
I am having some issues while forming template with respect to root
.
有什么建议吗?
推荐答案
您需要为名为 root2
的元素编写一个模板,并确保通过身份转换模板处理其余部分:>
You need to write a template for the element named root2
and make sure you handle the rest by the identity transformation template:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root2">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="not(self::value5 | self::value6 | self::value7)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:copy-of select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<country>
<xsl:copy-of select="current-group()"/>
</country>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XSLT 和 XQuery 都允许您基于表达式创建元素,而不是以 <country>...</country>
形式对文字结果元素进行硬编码.您使用的 XSLT 例如<xsl:element name="{expression}">...</xsl:element>
,在 XQuery element {expression} {...}
.所以你当然可以像在 https://xsltfiddle.liberty-development 中所做的那样声明一个全局参数.net/gWmuiJJ/0, https://xsltfiddle.liberty-development.net/gWmuiJJ/1, https://xsltfiddle.liberty-development.net/gWmuiJJ/2
Instead of hard coding a literal result element in the form of <country>...</country>
both XSLT and XQuery allow you to create an element based on an expression, in XSLT you use e.g. <xsl:element name="{expression}">...</xsl:element>
, in XQuery element {expression} {...}
. So you can certainly declare something like a global parameter as done in https://xsltfiddle.liberty-development.net/gWmuiJJ/0, https://xsltfiddle.liberty-development.net/gWmuiJJ/1, https://xsltfiddle.liberty-development.net/gWmuiJJ/2
,例如
<xsl:param name="wrapper-name"
select="if (/* instance of element(biology))
then 'fruits'
else if (/* instance of element(geography))
then 'countries'
else 'wrapper'"/>
并使用它
<xsl:element name="{$wrapper-name}">
<xsl:copy-of select="current-group()"/>
</xsl:element>
这篇关于如何使用 for-each-group 包裹 XSLT 中的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!