如何使用for-each-groups对XSLT中的元素进行WRAP?

问题描述 投票:0回答:1

我想在使用XSLT的单个节点调用COUNTRY中将value5包装到value7

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

有什么建议?

xml xslt-2.0
1个回答
1
投票

您需要为名为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>,在XQuery element {expression} {...}。所以你当然可以在https://xsltfiddle.liberty-development.net/gWmuiJJ/0https://xsltfiddle.liberty-development.net/gWmuiJJ/1https://xsltfiddle.liberty-development.net/gWmuiJJ/2中声明类似全局参数的东西。

,e。

  <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>
© www.soinside.com 2019 - 2024. All rights reserved.