我正在寻找一个示例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结束。还有另一个x元素从37到55,y元素从18到26.输出列表的顺序并不重要。
我已经看过substring-before
和count
的提及但我无法弄清楚这些工作如何嵌套在未知数量的嵌套中,或者是否可能存在多个嵌套相同的元素出现在文本的各个部分。
只有XSLT可以这样吗?
答案 0 :(得分:3)
这是一个XSLT 1.0选项,非常类似于Martin的......
<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
答案 1 :(得分:2)
使用
<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 method="text"/>
<xsl:template match="node()">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="beta//*">
<xsl:variable name="preceding-length" select="sum((preceding::text() intersect ancestor::beta//text())/string-length())"/>
<xsl:value-of select="local-name(), ': ', $preceding-length, ', ', $preceding-length + string-length()"/>
<xsl:text> </xsl:text>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
和你的样本给我的XSLT 2.0处理器
x : 11 , 34
y : 21 , 29
x : 40 , 58
您想要的结果偏移3可能是空格。