XSLT 根据包含元素的属性值分解 XML 文本在 TEI 中不起作用
XSLT breaking up XML text based on the value of an attribute of a containing element doesn't work in TEI
我有一个很好的 XSLT 代码,可以根据文件中的空格将 XML 文件中 'p'(段落)元素的文本分解为 'w'(单词)元素细绳。
但是,我只希望它影响属性 @xml:lang 的值为 'arn' 的 'p' 元素。 (我还希望新的 'w' 元素继承 '@xml:lang='arn'' 属性和值,但这是次要的)。
我通过将“p[@xml:lang='arn']/text()”添加到我的匹配模板来修改代码。这对于普通的 XML 文件来说工作正常,但是当我尝试转换 TEI 文件时,文件又恢复原样。
这是我的输入:
<?xml version="1.0" encoding="UTF-8"?>
<text>
<body>
<div>
<p xml:lang="arn">Fei meu nùkei neməl təfa</p>
<p xml:lang="spa">Entonces toma la palabra él</p>
<p xml:lang="arn">Fei meu nùkei neməl təfa</p>
<p xml:lang="spa">Entonces toma la palabra él</p>
</div>
</body></text>
还有我的 XSLT:
<?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()" priority="-1">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p[@xml:lang='arn']/text()[normalize-space()]">
<xsl:variable name='orig' select="."/>
<xsl:variable name='lang' select="$orig/ancestor::*[normalize-space(@xml:lang)][1]/@xml:lang"/>
<xsl:analyze-string select="." regex="[\p{{L}}\p{{N}}]+">
<xsl:matching-substring>
<xsl:element name="w">
<xsl:attribute name="xml:lang"><xsl:value-of select="$lang"/></xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
这给了我想要的输出:
<?xml version="1.0" encoding="UTF-8"?><text>
<body>
<div>
<p xml:lang="arn"><w xml:lang="arn">Fei</w> <w xml:lang="arn">meu</w> <w xml:lang="arn">nùkei</w> <w xml:lang="arn">neməl</w> <w xml:lang="arn">təfa</w></p>
<p xml:lang="spa">Entonces toma la palabra él</p>
<p xml:lang="arn"><w xml:lang="arn">Fei</w> <w xml:lang="arn">meu</w> <w xml:lang="arn">nùkei</w> <w xml:lang="arn">neməl</w> <w xml:lang="arn">təfa</w></p>
<p xml:lang="spa">Entonces toma la palabra él</p>
</div>
</body></text>
然而,当输入有一个TEI header,如下,我取回了输入文件。
<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<teiHeader>
<fileDesc>
<titleStmt>
<title></title>
</titleStmt>
<publicationStmt><ab></ab></publicationStmt>
<sourceDesc><ab></ab></sourceDesc>
</fileDesc>
</teiHeader>
<text>
<body>
<div>
<p xml:lang="arn">Fei meu nùkei neməl təfa</p>
<p xml:lang="spa">Entonces toma la palabra él</p>
<p xml:lang="arn">Fei meu nùkei neməl təfa</p>
<p xml:lang="spa">Entonces toma la palabra él</p>
</div>
</body></text>
</TEI>
有什么避免这种情况的建议吗?
在第二个版本中,您的整个 XML 都在默认命名空间 "http://www.tei-c.org/ns/1.0"
中。所以在根元素上定义的这个命名空间的所有子元素都在同一个命名空间中。
一个简单的解决方案是添加行
xpath-default-namespace="http://www.tei-c.org/ns/1.0"
XSLT 的 xsl:stylesheet
元素。
我有一个很好的 XSLT 代码,可以根据文件中的空格将 XML 文件中 'p'(段落)元素的文本分解为 'w'(单词)元素细绳。 但是,我只希望它影响属性 @xml:lang 的值为 'arn' 的 'p' 元素。 (我还希望新的 'w' 元素继承 '@xml:lang='arn'' 属性和值,但这是次要的)。 我通过将“p[@xml:lang='arn']/text()”添加到我的匹配模板来修改代码。这对于普通的 XML 文件来说工作正常,但是当我尝试转换 TEI 文件时,文件又恢复原样。
这是我的输入:
<?xml version="1.0" encoding="UTF-8"?>
<text>
<body>
<div>
<p xml:lang="arn">Fei meu nùkei neməl təfa</p>
<p xml:lang="spa">Entonces toma la palabra él</p>
<p xml:lang="arn">Fei meu nùkei neməl təfa</p>
<p xml:lang="spa">Entonces toma la palabra él</p>
</div>
</body></text>
还有我的 XSLT:
<?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()" priority="-1">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p[@xml:lang='arn']/text()[normalize-space()]">
<xsl:variable name='orig' select="."/>
<xsl:variable name='lang' select="$orig/ancestor::*[normalize-space(@xml:lang)][1]/@xml:lang"/>
<xsl:analyze-string select="." regex="[\p{{L}}\p{{N}}]+">
<xsl:matching-substring>
<xsl:element name="w">
<xsl:attribute name="xml:lang"><xsl:value-of select="$lang"/></xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
这给了我想要的输出:
<?xml version="1.0" encoding="UTF-8"?><text>
<body>
<div>
<p xml:lang="arn"><w xml:lang="arn">Fei</w> <w xml:lang="arn">meu</w> <w xml:lang="arn">nùkei</w> <w xml:lang="arn">neməl</w> <w xml:lang="arn">təfa</w></p>
<p xml:lang="spa">Entonces toma la palabra él</p>
<p xml:lang="arn"><w xml:lang="arn">Fei</w> <w xml:lang="arn">meu</w> <w xml:lang="arn">nùkei</w> <w xml:lang="arn">neməl</w> <w xml:lang="arn">təfa</w></p>
<p xml:lang="spa">Entonces toma la palabra él</p>
</div>
</body></text>
然而,当输入有一个TEI header,如下,我取回了输入文件。
<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<teiHeader>
<fileDesc>
<titleStmt>
<title></title>
</titleStmt>
<publicationStmt><ab></ab></publicationStmt>
<sourceDesc><ab></ab></sourceDesc>
</fileDesc>
</teiHeader>
<text>
<body>
<div>
<p xml:lang="arn">Fei meu nùkei neməl təfa</p>
<p xml:lang="spa">Entonces toma la palabra él</p>
<p xml:lang="arn">Fei meu nùkei neməl təfa</p>
<p xml:lang="spa">Entonces toma la palabra él</p>
</div>
</body></text>
</TEI>
有什么避免这种情况的建议吗?
在第二个版本中,您的整个 XML 都在默认命名空间 "http://www.tei-c.org/ns/1.0"
中。所以在根元素上定义的这个命名空间的所有子元素都在同一个命名空间中。
一个简单的解决方案是添加行
xpath-default-namespace="http://www.tei-c.org/ns/1.0"
XSLT 的 xsl:stylesheet
元素。