XSLT:合并子元素

时间:2017-06-04 03:29:17

标签: xslt-2.0

您好我正在尝试将子节点合并到包含所有数据的单个节点中。

这是我的示例XML,

<root>
<list>
<label>Label 1</label>
    <item>some text</item>
<label>Label 2</label>
    <item>some text</item>
    <item>some more text </item>
    <item>some more text</item>
<label>Label 3</label>
    <item>other text</item>
    <item>some text</item>
    <item>some more text</item>
</list>
</root>

我需要将label元素后面的项节点合并到一个组中,并将内容合并到

标签中。期望的输出如下所示

<root>
    <list>
    <label>Label 1</label>
        <item>some text</item>
    <label>Label 2</label>
        <item><p>some text</p>
        <p>some more text </p>
        <p>some more text</p></item>
    <label>Label 3</label>
        <item><p>other text</p>
        <p>some text</p>
        <p>some more text</p></item>
    </list>
</root>

到目前为止,我尝试使用以下模板但不能正常工作,它将所有项目合并为一个,但我需要将它们标记为单独的p标记。谢谢你的帮助。

<xsl:template match="list">
    <xsl:copy>
        <xsl:for-each-group select="*" group-adjacent="boolean(self::item)">
            <xsl:choose>
                <xsl:when test="current-grouping-key()">
                    <item>
                        <xsl:apply-templates select="current-group()/node()"/>
                    </item>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="current-group()"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

1 个答案:

答案 0 :(得分:0)

我认为您已接近,您只需要确保使用创建item元素的模板处理已分组的p元素:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:output indent="yes"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="list">
    <xsl:copy>
        <xsl:for-each-group select="*" group-adjacent="boolean(self::item)">
            <xsl:choose>
                <xsl:when test="current-grouping-key()">
                    <item>
                        <xsl:apply-templates select="current-group()"/>
                    </item>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="current-group()"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each-group>
    </xsl:copy>
    </xsl:template>

    <xsl:template match="item">
        <p>
            <xsl:apply-templates/>
        </p>
    </xsl:template>
</xsl:transform>

那样(http://xsltransform.net/naZXpWX)我得到了

<root>
   <list>
      <label>Label 1</label>
      <item>
         <p>some text</p>
      </item>
      <label>Label 2</label>
      <item>
         <p>some text</p>
         <p>some more text </p>
         <p>some more text</p>
      </item>
      <label>Label 3</label>
      <item>
         <p>other text</p>
         <p>some text</p>
         <p>some more text</p>
      </item>
   </list>
</root>

这与您发布的预期结果略有不同,我不确定您发布的示例中是否存在错误,或者您是否希望以不同的方式处理只有一个item的群组,您可以使用在for-each-group

内进行额外检查
<xsl:template match="list">
<xsl:copy>
    <xsl:for-each-group select="*" group-adjacent="boolean(self::item)">
        <xsl:choose>
            <xsl:when test="current-grouping-key()">
                <item>
                    <xsl:choose>
                        <xsl:when test="current-group()[2]">
                            <xsl:apply-templates select="current-group()"/>                             
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:apply-templates/>
                        </xsl:otherwise>
                    </xsl:choose>
                </item>
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates select="current-group()"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each-group>
</xsl:copy>
</xsl:template>

http://xsltransform.net/naZXpWX/1

中完成