XSLT 在特定元素之间包裹节点

2024-04-14

我有以下 TEI 文件

<text>
    <pb n="1"/>
    <div>
        <head>title1</head>     
        <div>
            <head>title2</head>
            <l>line</l>
            <lg>1
                <l>line</l>
                <l>line</l>
            </lg>
            <lg>2
                <l>line</l>
                <pb n="2"/>
                <l>line</l>
            </lg>
            <lg>3
                <l>line</l>
                <l>line</l>
            </lg>
            <pb n="3"/>
            <lg>4
                <l>line</l>
                <l>line</l>
            </lg>
        </div>
    </div>
</text>

我需要选择最后一次出现的 pb 元素到下一个元素之间的节点并换行到页面标记。 pb 元素可以位于文档的任何级别

我的模板:

<xsl:key name="pageNo" match="node()" use="preceding-sibling::pb[@n][1]/@n"/>

<xsl:template match="text" >
    <xsl:for-each select="descendant::pb">
        <xsl:element name="page">
            <xsl:copy-of select="key('pageNo',@n)"/> 
        </xsl:element>
    </xsl:for-each>
</xsl:template>

转换后期望的文档:

<text>
    <page n="1">
        <div>
            <head>title1</head>     
            <div>
                <head>title2</head>
                <l>line1</l>
                <lg>1
                    <l>line</line>
                    <l>line</line>
                </lg>
                <lg>2
                    <l>line</line>
                </lg>
            </div>
        </div>
    </page>
    <page n="2">
        <div>
            <div>
                <lg>
                    <l>line</line>
                </lg>
                <lg>3
                    <l>line</line>
                    <l>line</line>
                </lg>
            </div>
        </div>
    </page>
    <page n="3">
        <div>
            <div>
                <lg>4
                    <l>line</line>
                    <l>line</line>
                </lg>
            </div>
        </div>
    </page>
</text>

通过 XSLT 2.0,您可以使用for-each-group select="node()" group-starting-with="pb":

<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:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="text">
        <xsl:copy>
            <xsl:variable name="parent" select="."/>
            <xsl:for-each-group select="descendant::node()" group-starting-with="pb[@n]">
                <page n="{@n}">
                    <xsl:apply-templates select="$parent/node()[descendant-or-self::node() intersect current-group()]" mode="subtree"/>
                </page>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="pb[@n]" mode="subtree"/>

    <xsl:template match="node()" mode="subtree">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates select="node()[descendant-or-self::node() intersect current-group()]" mode="subtree"/>
            </xsl:copy>

    </xsl:template>

</xsl:stylesheet>

对于您发布的输入,这给出了想要的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

XSLT 在特定元素之间包裹节点 的相关文章

随机推荐