【问题标题】:Duplicating node if复制节点如果
【发布时间】:2014-10-02 10:15:31
【问题描述】:

我无法完全解决这个问题 - 我很少使用 XSLT。在某种情况下,我需要复制一个节点。我看过“模板”和“副本”,但不知道如何让它们一起工作。

我拥有的 XML

<data>
  <product>
    <productnumber>655.43</productnumber>
    <parentproduct></parentproduct>
  </product>
  <product>
    <productnumber>655.38</productnumber>
    <parentproduct>655.43</parentproduct>
  </product>
</data>

我想要的 XML

<data>
  <product>
    <productnumber>655</productnumber>
    <parentproduct></parentproduct>
  </product>
  <product>
    <productnumber>655.43</productnumber>
    <parentproduct>655</parentproduct>
  </product>
  <product>
    <productnumber>655.38</productnumber>
    <parentproduct>655</parentproduct>
  </product>
<data>

因此,如果 parentproduct 为空,则应该复制产品节点。

我搞砸的 xsl 看起来像

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output cdata-section-elements="column"/>
<xsl:template match="/data/product">
    <xsl:copy>
        <xsl: apply-templates select="/data/product"/>
    </xsl:copy>
</xsl:template>

所以我需要在 apply-templates 的 select 语句中添加一些“东西”...但无法弄清楚。

提前感谢您的帮助! 问候 /Snedker

【问题讨论】:

  • "因此,如果 parentproduct 为空,则应复制产品节点。" 这不是您的示例显示的内容 - 请澄清。
  • 655.43 表示 655 是主要产品 (ProductID),43 表示变体 (VariantID)。表中必须有一行具有 ProductID 且没有 VariantID(主)。接下来,所有变体行都有 ProductID+VariantID。我的麻烦是主人(没有父产品)也充当变体(因此产品中的内容)。 “我想要的 XML”显示一个主产品 + 两个变体。希望这可以澄清。并感谢您的努力! BR /莫腾
  • 恐怕我还没有完全和你在一起。输入 XML 显示 655.43 是 655.38 的父产品。此信息在转换中丢失。你确定这就是你想要的吗?
  • 是的,我确定。问题在于 655.43 既包含作为父代的信息(空 )又包含变体的信息(.43)。我需要拆分此信息,以便父​​产品没有变体信息。这样所有的变体都指向一个没有变体信息的父代(在这种情况下只是:655)。然后所有变体都应该有 655
  • 我是否理解正确,该解决方案应该简单地忽略所有parentproduct 标签 - 是否为空 - 并将productnumber“变体”分组在一个共同的父级下,由整数部分给出号码?

标签: xml xslt copy xmlnode


【解决方案1】:

我觉得我在这里仍然缺少一些东西,但请尝试以下样式表:

XSLT 1.0

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

<xsl:key name="product-by-parent" match="productnumber" use="substring-before(., '.')" />

<xsl:template match="/">
    <data>
        <!-- for each unique integer part of productnumber -->
        <xsl:for-each select="data/product/productnumber[count(. | key('product-by-parent', substring-before(., '.'))[1]) = 1]">
            <xsl:variable name="parent" select=" substring-before(., '.')" />
            <product>
                <productnumber><xsl:value-of select="$parent"/></productnumber>
                <parentproduct/>
            </product>
            <!-- for each productnumber starting with the current integer -->
            <xsl:for-each select="key('product-by-parent',  $parent)">
                <product>
                    <productnumber><xsl:value-of select="."/></productnumber>
                    <parentproduct><xsl:value-of select="$parent"/></parentproduct>
                </product>
            </xsl:for-each>
        </xsl:for-each>
    </data>
</xsl:template>

</xsl:stylesheet>

恕我直言,您的输出架构可以通过将子产品包装在一个公共父元素中来改进。

【讨论】:

    【解决方案2】:

    我建议你最好使用&lt;xsl:copy-of select="."/&gt;,它会复制当前节点的精确全深度副本。

    【讨论】:

    • 我发现的信息表明,复制不利于属性的后续操作。但我是菜鸟,所以我可能是错的。谢谢你的输入! BR
    猜你喜欢
    • 2017-01-20
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 2015-12-28
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    相关资源
    最近更新 更多