xml - 使用 XSLT 从嵌套的 XML 结构生成元素文本位置的平面列表

标签 xml xslt xpath

我正在寻找一个示例 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-beforecount但我无法弄清楚当嵌套未知数量的嵌套或文本的不同部分可能存在几个相同元素时这些是如何工作的。

仅使用 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(),'&#xA;')"/>
    <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/

相关文章:

c# - 将参数传递给 XSLT 样式表

html - 如何在Firebug中获取元素的绝对XPath?

xpath - 带有 fn :substring-before 的 Xquery 错误

用于 XML 的 java api - 带磁盘备份的 dom 处理

C# 三个正斜杠 : can the template be changed?

xml - 这是有效的 XML 注释吗?

xml - 使用 XSLT 迭代具有命名空间的 XML 元素

xml - 只定义一个结构并让它在 Go 中处理 XML 文件的所有内部元素?

java - 使用 Maven 进行 XML/XSL 压缩

html - 要从不同的 xsl 文件访问 xslt 变量?