首页 > 解决方案 > 如何合并两个或多个连续的 'styled-content' 元素并转换为单个 while 属性相同?

问题描述

有多个具有不同属性 @style 和 @style-type 值的“样式内容”,在这里我们尝试仅合并属性值匹配的连续“样式内容”元素。以下是示例案例:

注意:元素 'styled-content' 可以有其他元素,如 'italic' 和 'bold'。这些元素也应该保留。此外,“styled-content”元素可能是“p”以外的不同父元素。

输入 XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<p content-type="new">For these purposes, the degree of relationship is determined as of the date of execution because of divorce. See <styled-content style="case" style-type="Case-Cal"><italic>Estate of Lira</italic></styled-content><styled-content style="case" style-type="Case-Cal"> (2012) 212 CA4th 1368</styled-content>.</p>
<p content-type="new">Under the <styled-content style="act" style-type="Act-Cal">Trust Law</styled-content>, you owe a duty (see <styled-content style="stat" style-type="Stat-Cal">Probate Code </styled-content><styled-content style="stat" style-type="Stat-Cal">&#x00a7;16061.5</styled-content>). We will discuss with you what specific actions you and we will take to fulfill these duties.</p>
<p content-type="new">Assets may be valued for federal estate tax purposes as of the alternate valuation date <styled-content style="case" style-type="Case-Federal"><italic>Estate of Edward H. Eddy</italic></styled-content><styled-content style="case" style-type="Case-Federal"> (2000) 115 TC </styled-content><styled-content style="case" style-type="Case-Federal">135</styled-content>. The IRS may grant an extension to make the election within the 1-year period even after a timely estate tax return has been filed.</p>
<p content-type="new">Prop Treas Reg see <styled-content style="pub" style-type="Ref-external-CEB"><italic>IRS Issues Temporary and Proposed Basis Consistency and Reporting Regulations,</italic></styled-content><styled-content style="pub" style-type="Ref-external-CEB"> 37 CEB Est Plan Rep 140 (Apr. 2016)</styled-content>.</p>
</root>

预期输出:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<p content-type="new">For these purposes, the degree of relationship is determined as of the date of execution because of divorce. See <styled-content style="case" style-type="Case-Cal"><italic>Estate of Lira</italic> (2012) 212 CA4th 1368</styled-content>.</p>
<p content-type="new">Under the <styled-content style="act" style-type="Act-Cal">Trust Law</styled-content>, you owe a duty (see <styled-content style="stat" style-type="Stat-Cal">Probate Code &#x00a7;16061.5</styled-content>). We will discuss with you what specific actions you and we will take to fulfill these duties.</p>
<p content-type="new">Assets may be valued for federal estate tax purposes as of the alternate valuation date <styled-content style="case" style-type="Case-Federal"><italic>Estate of Edward H. Eddy</italic> (2000) 115 TC 135</styled-content>. The IRS may grant an extension to make the election within the 1-year period even after a timely estate tax return has been filed.</p>
<p content-type="new">Prop Treas Reg see <styled-content style="pub" style-type="Ref-external-CEB"><italic>IRS Issues Temporary and Proposed Basis Consistency and Reporting Regulations,</italic> 37 CEB Est Plan Rep 140 (Apr. 2016)</styled-content>.</p>
</root>

XSLT 代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">

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

<xsl:template match="styled-content[@style[.='case'] and @style-type[.='Case-Cal']]">
    <styled-content>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates/>
        <xsl:if test="following-sibling::node()[1][self::styled-content[@style[.='case'] and @style-type[.='Case-Cal']]]">
            <xsl:apply-templates select="following-sibling::node()[1][self::styled-content[@style[.='case'] and @style-type[.='Case-Cal']]]/node()"/>
        </xsl:if>
    </styled-content>
</xsl:template>
<xsl:template match="styled-content[@style='case' and @style-type[.='Case-Cal']][preceding-sibling::node()[1][self::styled-content[@style='case' and @style-type[.='Case-Cal']]]]"/>

</xsl:stylesheet>

标签: xmlxpathxslt-2.0

解决方案


这似乎是一项任务for-each-group group-adjacent,在 XSLT 3(自 2017 年可用)中,它比在 XSLT 2 中更容易表达,因为 XSLT 3 允许复合分组键:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="*[styled-content]">
      <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:for-each-group 
              select="node()" 
              group-adjacent=". is element(styled-content), @style, @style-type" 
              composite="yes">
              <xsl:choose>
                  <xsl:when test="current-grouping-key()[1]">
                      <xsl:copy>
                          <xsl:apply-templates select="@*, current-group()/node()"/>
                      </xsl:copy>
                  </xsl:when>
                  <xsl:otherwise>
                      <xsl:apply-templates select="current-group()"/>
                  </xsl:otherwise>
              </xsl:choose>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bEzkTd6

如果您确实需要使用 XSLT 2,那么您需要删除composite="yes"、 更改group-adjacent=". is element(styled-content), @style, @style-type"togroup-adjacent="string-join((. is element(styled-content), @style, @style-type), '|')"<xsl:when test="current-grouping-key()[1]">to <xsl:when test=". is element(styled-content)">


推荐阅读