XSLT - 分组并丢失 parent 的文本

XSLT - grouping and lost parent's text

我遇到一个问题,当我尝试将代码行分组到块中时,我的 parent 的文本丢失了,我不知道为什么。

XML

<body>
  <ul>
    <li>before
      <filepath>one test</filepath> now some code:
      <codeblock>1</codeblock>
      <codeblock>2</codeblock>
      after text</li>
  </ul>
  <section>
    <title>Test2</title>
    <p>qqqq</p>
    <codeblock>1</codeblock>
    <codeblock>2</codeblock>
    <codeblock>3</codeblock>
  </section>
</body>

XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xsl:template match="@*|node()">
    <xsl:choose>
        <xsl:when test="./codeblock[1] or ./msgblock[1]">
            <xsl:call-template name="merge-codeblock">
                <xsl:with-param name="container" select="."/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy>
                <xsl:apply-templates select="@* | node()" />
            </xsl:copy>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="merge-codeblock">
    <xsl:param name="container"/>    
            <xsl:copy>
                <xsl:for-each-group select="*" group-adjacent="boolean(self::codeblock or self::msgblock)">
                    <xsl:choose>
                        <xsl:when test="current-grouping-key() and count(current-group()) gt 1">
                            <xsl:element name="{name()}">
                                <xsl:variable name="name" select="current-group()/node()" />
                                <xsl:for-each select="current-group()/node()">
                                    <xsl:variable name="namee" select="current()" />
                                    <xsl:apply-templates select="current()" />
                                    <xsl:text>&#10;</xsl:text>
                                </xsl:for-each>
                            </xsl:element>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:apply-templates select="current-group()" />
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each-group>
            </xsl:copy>        
</xsl:template>

</xsl:stylesheet>

当前结果

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "dtd/task.dtd"><!--<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "dtd/task.dtd">--><body>
   <ul>
      <li><!-- not ok! I lost my li/text() -->
         <filepath>one test</filepath>
         <codeblock>1
2
</codeblock>
      </li>
   </ul>
   <section>
      <title>Test</title>
      <p>fddsfsd</p>
      <codeblock>fdsfds</codeblock>
   </section>
   <section>
      <title>Test2</title>
      <p>qqqq</p>
      <codeblock>1
2
3
</codeblock>
   </section>
</body>

我已经尝试将 |text() 添加到我的组选择器中,这解决了问题,但是我的 codeblock 元素不再合并。

我做错了什么?

编辑: Martin 的回答解决了 LI 问题,但不幸的是,我现在在代码块行之前有额外的 spaces,在第一个代码块之后有一个回车 return:

<codeblock>
      1
      2
      3
</codeblock>

而不是:

<codeblock>1
2
3</codeblock>

我怎样才能摆脱这些,我已经尝试删除 current-group() 中的 spaces 但没有成功。

建议的编辑给我:

  <codeblock>

1


2


3

   </codeblock>

但是怪白的问题依旧space。 current-group() 包含 " ", <codeblock>, " ", <codeblock>, " ", <codeblock>, " ",空格 space 中有回车 return。

我觉得

<?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="*[codeblock | msgblock]">
        <xsl:copy>
            <xsl:for-each-group select="node()"
                group-adjacent="boolean(self::text()[not(normalize-space())] | self::codeblock | self::msgblock)">
                <xsl:choose>
                    <xsl:when test="current-grouping-key() and current-group()[self::*]">
                        <xsl:element name="{name(current-group()[self::*[1]][1])}">
                            <xsl:apply-templates select="current-group()"/>
                        </xsl:element>
                    </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="codeblock | msgblock">
        <xsl:apply-templates/>
    </xsl:template>
</xsl:stylesheet>

分组并保留文本,您可能需要调整输出分组内容的部分,因为我不确定您想要哪个确切结果。

关于白色 space 的问题,假设您在 codeblockmsgblock 元素中只有纯文本,那么您可以简化

                <xsl:choose>
                    <xsl:when test="current-grouping-key() and current-group()[self::*]">
                        <xsl:element name="{name(current-group()[self::*[1]][1])}">
                            <xsl:apply-templates select="current-group()"/>
                        </xsl:element>
                    </xsl:when>

                <xsl:choose>
                    <xsl:when test="current-grouping-key() and current-group()[self::*]">
                        <xsl:element name="{name(current-group()[self::*[1]][1])}">
                            <xsl:value-of select="current-group()[self::*]" separator="&#10;"/>
                        </xsl:element>
                    </xsl:when>