如何使用 for-each 组将元素包装在 XSLT 中?



我想使用XSLT将值5 包装为值 7 在单个节点调用COUNTRY

示例 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的模板时遇到了一些问题。

有什么建议吗?

您需要为名为root2的元素编写一个模板,并确保通过标识转换模板处理其余部分:

<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>,在XQueryelement {expression} {...}。因此,您当然可以声明类似于全局参数的内容,如在 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>

最新更新