XSLT 组织列表列表

问题描述 投票:0回答:1

我正在尝试重新处理列表列表,从 XML 转换为基于 XML 的专有文件格式。

输入本质上是这样的

<ul>
  <li>Item 1</li>
  <li><ul><li>Sub item 1</li><li>Sub item 2</li></ul></li>

  <li>Item 2</li>
  <li><ul><li>Sub item 3</li><li>Sub item 4</li></ul></li>
</ul>

显然看起来像这样:

  • 第 1 项
    • 子项目1
    • 子项目2
  • 第 2 项
    • 子项目3
    • 子项目4

但我需要将子项目列表放在相同的

li
标签中作为各自的标题。 所以,像这样:

  • 项目 1
    • 子项目 1
    • 子项目 2
  • 项目 2
    • 子项目 3
    • 子项目 4

当我测试上面的原始输入时,我似乎无法想出一个 XPATH 来拾取我的第一个子项目

ul
而不拾取第二个子项目
ul

当通过转换运行它时,这基本上会创建

<ul>
  <li>Item 1
    <ul><li>Sub item 1</li><li>Sub item 2</li></ul>
    <ul><li>Sub item 3</li><li>Sub item 4</li></ul>
  </li>

  <li>Item 2
    <ul><li>Sub item 3</li><li>Sub item 4</li></ul>
  </li>
</ul>

让我到目前为止的 XPath 是

following-sibling::li[not(normalize-space(text()))]/*[1][self::ul or self::ol]
  

归一化空间是隔离一个

li
,它没有文本,但里面只有
ul
ol
。我已经尝试了上述的多种变体,设置索引 [1] 只是返回它们全部,[2] 什么也不返回。

我有点困惑,感谢任何意见或建议!

xpath xslt
1个回答
0
投票

这似乎是一个分组问题,您可以在 XSLT 2 或更高版本(XSLT 的当前版本是 3.0)中使用

for-each-group group-starting-with
:

来解决
  <xsl:template match="ul[.//ul]">
    <xsl:copy>
      <xsl:for-each-group select="li" group-starting-with="li[not(ul)]">
        <xsl:copy>
          <xsl:apply-templates select="node(), tail(current-group())/*"/>
        </xsl:copy>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

示例小提琴是这里

© www.soinside.com 2019 - 2024. All rights reserved.