如何使用 for-each-group 包裹 XSLT 中的元素? [英] How to WRAP the elements in XSLT using for-each-group?

查看:17
本文介绍了如何使用 for-each-group 包裹 XSLT 中的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆