在以下元素的花括号之间获取文本,并使用xslt合并文本

时间:2019-10-29 04:55:06

标签: xml xslt xslt-2.0

我想在花括号之间获取文本,然后将孔文本合并为一个元素

我的XML输入位于一个td内,r和t元素包含需要将一个t元素与一个td合并在一起的文本:

<topic>
<body>
<table>
<tr><td><p id="1"><pPr><pstyle class="normal"/></pPr>
<r><t>{</t></r>
<r><t>Ram</t></r>
<r><t>Ramt}</t></r>
</p></td></tr>
<tr><td><p id="2"><pPr><pstyle class="normal"/></pPr>
<r><t>{Red</t></r>
<r><t>Sham</t></r>
<r><t>}</t></r>
</p></td></tr>
<tr><td><p id="3"><pPr><pstyle class="normal"/></pPr>
<r><t>{Red</t></r>
<r><t>}</t></r>
</p></td></tr>
<tr><td><p id="4"><pPr><pstyle class="normal"/></pPr>
<r><t>{Damn}</t></r>
</p></td></tr>
</table>
</body>
</topic>

我曾经使用XSLT提取花括号文本,以检查是否凝视并结束了卷曲,然后应用了模板:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform>
<xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="r/t">
        <xsl:choose>
            <xsl:when test="starts-with(t, '{') and ends-with(t, '}')">
                <r><t><xsl:apply-templates/></t></r>
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:transform>

我得到的输出是只有r个元素的值,没有组合,而t个元素也不存在

<topic>
<body>
<table>
<tr><td><p id="1"><pPr>
<pstyle class="normal"></pstyle>
</pPr>
<r>{</r>
<r>Ram</r>
<r>Ramt}</r>
</p></td></tr>
<tr><td><p id="2"><pPr><pstyle class="normal"></pstyle></pPr>
<r>{Red</r>
<r>Sham</r>
<r>}</r>
</p></td></tr>
<tr><td><p id="3"><pPr><pstyle class="normal"></pstyle></pPr>
<r>{Red</r>
<r>}</r>
</p></td></tr>
<tr><td><p id="4"><pPr><pstyle class="normal"></pstyle></pPr>
<r>{Damn}</r>
</p></td></tr>
</table>
</body>
</topic>

需要在r元素内的元素文本中组合输出:

<topic>
<body>
<table>
<tr><td><p id="1"><pPr><pstyle class="normal"/></pPr>
<r><t>{RamRamt}</t></r>
</p></td></tr>
<tr><td><p id="2"><pPr><pstyle class="normal"/></pPr>
<r><t>{RedSham}</t></r>
</p></td></tr>
<tr><td><p id="3"><pPr><pstyle class="normal"/></pPr>
<r><t>{Red}</t></r>
</p></td></tr>
<tr><td><p id="4"><pPr><pstyle class="normal"/></pPr>
<r><t>{Damn}</t></r>
</p></td></tr>
</table>
</body>
</topic>

请告知

1 个答案:

答案 0 :(得分:1)

这里尝试使用for-each-group

  <xsl:template match="p[r/t]">
      <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:for-each-group select="*" group-adjacent="boolean(self::r[t])">
              <xsl:choose>
                  <xsl:when test="current-grouping-key()">
                      <xsl:for-each-group select="current-group()" group-starting-with="r[t[starts-with(., '{')]]">
                          <xsl:for-each-group select="current-group()" group-ending-with="r[t[ends-with(., '}')]]">
                              <r><t><xsl:apply-templates select="current-group()/t/text()"/></t></r>
                          </xsl:for-each-group>
                      </xsl:for-each-group>
                  </xsl:when>
                  <xsl:otherwise>
                      <xsl:apply-templates select="current-group()"/>
                  </xsl:otherwise>
              </xsl:choose>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

假设将身份转换设置为基本转换步骤,例如在XSLT 3(https://xsltfiddle.liberty-development.net/94AbWB4)中使用<xsl:mode on-no-match="shallow-copy"/>或使用等效模板将其拼写出来。

以上内容并未涵盖所有极端情况,但您尚未真正阐明是否可以包含其他内容;应该有可能调整分组条件和/或内部choose/when测试以改进代码以处理更多可变内容。