【问题标题】:Need to split and distribute xslt nodes需要拆分和分发xslt节点
【发布时间】:2023-07-10 06:12:02
【问题描述】:

需要使用 XSLT 2.0 或 3.0 转换下面提到的 XML 结构,

来自

<RD>
    <RE>
        <BI>B00</BI>
        <BI>B01</BI>
        <BI>B02</BI>
        <BI>B03</BI>
        <CI>C01</CI>
        <D>D01</D>
    </RE>
    <RE>
        <BI>B04</BI>
        <BI>B05</BI>
        <CI>C02</CI>
        <D>D02</D>
    </RE>
</RD>

到这里:

<RD>
    <RE>
        <BI>B00</BI>
        <CI>C01</CI>
        <D>D01</D>
    </RE>
    <RE>
        <BI>B01</BI>
        <CI>C01</CI>
        <D>D01</DI>
    </RE>
    <RE>
        <BI>B02</BI>
        <CI>C01</CI>
        <D>D01</D>
    </RE>
    <RE>
        <BI>B03</BI>
        <CI>C01</CI>
        <D>D01</D>
    </RE>
    <RE>
        <BI>B04</BI>
        <CI>C02</CI>
        <D>D02</D>
    </RE>
    <RE>
        <BI>B05</BI>
        <CI>C02</CI>
        <D>D02</D>
    </RE>
</RD>

说明: 我需要在(RE)标签的每次迭代中实现(CI),(D)的XML节点到每个(BI)标签的分布

【问题讨论】:

  • 我在您的示例中没有看到 (L)、(T)、(SN) 或 (r)。并且您的输出有 &lt;BI&gt;S03&lt;/BI&gt; 输入中不存在。
  • 帖子中的错误已更正。谢谢
  • 看看这是否有帮助:*.com/a/32496962/3016153
  • 你尝试了什么?什么不工作?

标签: xml xslt xslt-2.0 transformation


【解决方案1】:

您可以将其视为分组问题:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  expand-text="yes">

  <xsl:output method="xml" indent="yes"/>
  
  <xsl:template match="RD">
    <xsl:copy>
      <xsl:for-each-group select="RE" group-by="BI">
        <xsl:copy>
          <BI>{current-grouping-key()}</BI>
          <xsl:apply-templates select="*[not(self::BI)]"/>
        </xsl:copy>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

  <xsl:mode on-no-match="shallow-copy"/>

</xsl:stylesheet>

【讨论】:

  • 我绝不会想到只有一个CI 和一个D。这当然使问题变得微不足道。您甚至不需要在这里使用分组 - 只需将两个兄弟姐妹添加到每个 BI
【解决方案2】:

这也可以像这样简单地解决:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="RD">
    <xsl:copy>
      <xsl:apply-templates select="RE/BI"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="BI">
    <RE>
      <xsl:copy-of select="."/>
      <xsl:copy-of select="following-sibling::CI"/>
      <xsl:copy-of select="following-sibling::D"/>
    </RE>
  </xsl:template>
  
</xsl:stylesheet>

在这里看到它的工作:https://xsltfiddle.liberty-development.net/gVK6D4y

【讨论】:

【解决方案3】:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output indent="yes"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="RE">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="BI">
        <RE>
            <xsl:copy-of select="."/>
            <xsl:copy-of select="following-sibling::*[not(self::BI)]"/>
        </RE>
    </xsl:template>

</xsl:stylesheet>

【讨论】: