代码之家  ›  专栏  ›  技术社区  ›  Daniel

合并插入文本的直接兄弟元素

  •  0
  • Daniel  · 技术社区  · 21 小时前

    如果这已经在另一篇帖子中被问到并得到了回答,我提前道歉。

    我一直在思考这个问题,但还没有找到一个完整的解决方案。

    我的问题是:

    我有几个案例,其中父元素包含多组直接的兄弟元素。每个集合都需要与它们的任何子元素合并到一个元素中。每组都穿插着文字。例如:

    XML输入

    <p>Information about specific mio levels, accessed as 
    <codeph><i>metaMio</i></codeph><codeph>[</codeph><codeph><i>N</i></codeph><codeph>]</codeph>
    , in which
    <codeph><i>N</i></codeph><codeph> &lt; kMaxMioLevels</codeph>
    .
    </p>
    

    所需的XML输出

    <p>Information about specific mio levels, accessed as 
    <codeph><i>metaMio</i>[<i>N</i>]</codeph>
    , in which
    <codeph><i>N</i> &lt; kMaxMioLevels</codeph>
    .
    </p>
    

    这是我到目前为止所尝试的,但我发现它重复了第二组中第二个元素的内容:

    尝试XSLT

        <xsl:template match="codeph[not(preceding-sibling::node()[1][./local-name()='codeph'])][following-sibling::node()[1][./local-name()='codeph']]">
            <xsl:copy copy-namespaces="no">
                <xsl:apply-templates/>
                <xsl:choose>
                    <xsl:when test="following-sibling::codeph[preceding-sibling::node()[position()=1][local-name()='codeph']]">
                        <xsl:apply-templates select="following-sibling::codeph[preceding-sibling::node()[position()=1][local-name()='codeph']]" mode="codeph-merger"/>
                    </xsl:when>
                    <xsl:when test="following-sibling::*[1][text()[not(parent::codeph)]]"/>
                </xsl:choose>            
            </xsl:copy>
        </xsl:template>
        
        <xsl:template match="*" mode="codeph-merger">
            <xsl:apply-templates/>
        </xsl:template>
        
        <xsl:template match="codeph[preceding-sibling::node()[1][local-name()='codeph']]"/>
    

    电流输出

    上面的XSLT创建了以下输出,该输出很接近,但重复了文本( &lt; kMaxMipLevels ):

    <p>Information about specific mio levels, accessed as
    <codeph><i>metaMio</i>[<i>N</i>] &lt; kMaxMipLevels</codeph>
    , in which 
    <codeph><i>N</i> &lt; kMaxMipLevels</codeph>
    .
    </p>
    

    我还尝试将组邻近用作xsl:for-each组的一部分,但找不到任何方法来处理这种情况。

    我使用XSLT 2.0和Saxon HE 12.4作为DITA-OT 4.2.4的一部分。

    感谢您提供的任何帮助。

    1 回复  |  直到 21 小时前
        1
  •  1
  •   michael.hor257k    19 小时前

    更好地解释所需的逻辑将是有益的。事实上,在给定的示例中,以下代码似乎产生了所需的结果:

    XSLT 2.0

    <xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="p[codeph]">
        <xsl:copy>
            <xsl:for-each-group select="codeph|text()" group-adjacent="boolean(self::codeph)">  
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                        <codeph>
                            <xsl:apply-templates select="current-group()/node()"/> 
                        </codeph>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()"/> 
                    </xsl:otherwise>  
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>