0

我有 TEI(文本编码倡议)文件,其中包含

<div>
  <p>
     some text, and maybe nodes <note>A note</note><lb />
     and some more text<lb />
     final line without lb
  </p>
</div>

我想将其转换为:

<div>
  <lg>
     <l>some text, and maybe nodes <note>A note</note></l>
     <l>and some more text</l>
     <l>final line without lb</l>
  </lg>
</div>

通过使用将 p 转换为 lg 很简单

<xsl:template match="tei:div/tei:p">
   <lg>
     <xsl:apply-templates/>
   </lg>
</xsl:template>

但其余的我不知道该怎么做。将一系列节点变成新父节点的子节点。

如果有 xslt 1.0 的解决方案,那就太好了。

4

2 回答 2

1

这是您可以查看的另一种方式。它使用一个将每个节点链接到它最近的前一个lb分隔符。这使您能够通过前导分隔符的唯一 id 获取每个组(除了第一个组):

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:key name="following-nodes" match="node()[not(self::lb)]" use="generate-id(preceding-sibling::lb[1])" />

<xsl:template match="p[lb]">
    <lg>
        <l>
            <xsl:apply-templates select="lb[1]/preceding-sibling::node()"/>
        </l>
        <xsl:for-each select="lb">
            <l>
                <xsl:apply-templates select="key('following-nodes', generate-id())"/>
            </l>
        </xsl:for-each>
    </lg>
</xsl:template>

</xsl:stylesheet>

此示例不使用命名空间,因为您的问题没有定义它们。

于 2017-03-17T17:10:22.330 回答
0

您可以在这里使用一种称为Muenchian 分组的技术。p在这种情况下,您可以按照元素的数量对lb元素的子节点进行分组

<xsl:key name="p-nodes" match="tei:p/node()" use="concat(generate-id(..), '|', count(following-sibling::tei:lb))" />

要获得每个组中的第一个节点,它将代表l您想要输出的每个节点,您可以像这样选择它们......

<xsl:for-each
     select="node()[generate-id() = generate-id(key('p-nodes', concat($parentId, '|', count(following-sibling::tei:lb)))[1])]">

并输出<l>标签本身和组的内容,再次使用密钥...

<l><xsl:apply-templates select="key('p-nodes', concat($parentId, '|', count(following-sibling::tei:lb)))[not(self::tei:lb)]" /></l>

试试这个 XSLT(显然更改tei前缀的名称空间以匹配 XML 中的真实名称)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:tei="tei">
    <xsl:output method="xml" indent="yes" />

    <xsl:key name="p-nodes" match="tei:p/node()" use="concat(generate-id(..), '|', count(following-sibling::tei:lb))" />

    <xsl:template match="tei:div/tei:p">
       <lg>
            <xsl:variable name="parentId" select="generate-id()" />
            <xsl:for-each select="node()[generate-id() = generate-id(key('p-nodes', concat($parentId, '|', count(following-sibling::tei:lb)))[1])]">
                <l><xsl:apply-templates select="key('p-nodes', concat($parentId, '|', count(following-sibling::tei:lb)))[not(self::tei:lb)]" /></l>
            </xsl:for-each>
       </lg>
    </xsl:template>

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

在http://xsltransform.net/gWEamMf上查看它的实际应用

于 2017-03-17T16:56:14.867 回答