我正在寻找一个示例 XML,例如
<alpha>
<beta>
Here is <x>some text <y>and more</y> text</x> with <x>a little more text</x>!
</beta>
</alpha>
我正在尝试使用 XSL 将其转换为类似
x:8,31
x:37,55
y:18,26
确切的格式并不重要,我要弄清楚的主要任务是获取各种
<x>
的文本中的位置。和 <y>
元素(可以多次表示并嵌套,如示例所示,其中我有两个 <x>
元素,<y>
元素内有一个 <x>
元素)。所以上面想要的输出是说一个 x 元素从文本位置 8 开始,到 <beta>
内的文本位置 31 结束。元素。还有一个从 37 到 55 的 x 元素,还有一个从 18 到 26 的 y 元素。输出列表的顺序并不重要。我见过提到
substring-before
和 count
但我无法弄清楚当嵌套未知数量的嵌套或文本的不同部分可能存在几个相同元素时这些是如何工作的。仅使用 XSLT 就可以实现这样的事情吗?
最佳答案
这是一个与 Martin 的非常相似的 XSLT 1.0 选项...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="text()"/>
<xsl:template match="x|y">
<xsl:variable name="ancestor"
select="generate-id(ancestor::*[not(self::x) and not(self::y)][1])"/>
<xsl:variable name="preceding">
<xsl:for-each select="preceding::text()[ancestor::*[generate-id()=$ancestor]]">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="concat(name(),':',string-length($preceding),',',
string-length($preceding) + string-length(),'
')"/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
就像 Martin 提到的,
beta
中的空格很重要,因为它包含混合内容(文本和元素子元素)。如果删除前导/尾随空格...
<alpha>
<beta>Here is <x>some text <y>and more</y> text</x> with <x>a little more text</x>!</beta>
</alpha>
输出按要求...
x:8,31
y:18,26
x:37,55
关于xml - 使用 XSLT 从嵌套的 XML 结构生成元素文本位置的平面列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44831677/