Xslt将元素复制到现有元素,如果不存在则创建新元素

时间:2019-03-29 13:02:32

标签: xslt

对于xml转换来说是相当新的东西,我被困在(可能适合您)非常简单的任务。 让我们建议我们有来源:

<root>
  <someValue>123</someValue>
</root>

应将其转换为:

<root>
 <additional>
   <someValue>123</someValue>
 </additional>
</root>

但是,如果我们以此为来源:

<root>
 <additional>
  <b>something</b>
 </additional>
 <someValue>123</someValue>
</root>

我们应该将 someValue 移至现有的其他,即:

<root>
 <additional>
  <b>something</b>
  <someValue>123</someValue>
 </additional>     
</root>

请记住,在 a 级别上可能还有其他具有相同行为的元素(在其他下移动)。 好吧,工作示例受到人们的赞赏,但是如果它附有对其工作原理的简短描述,那将是很棒的(我更喜欢钓鱼,而不是单单摄食它。)

4 个答案:

答案 0 :(得分:2)

一种可能的方法是添加一个additional包装器作为root的子包装,并删除现有的additional包装器-使其子包装向上移动,成为{{1 }}(或者是添加的root包装器的子级):

XSLT 1.0

additional

答案 1 :(得分:1)

  

请记住,在a级别上可能还有其他相同的元素   行为(在additional下移动)。

此样式表:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="root[additional|someValue]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <additional>
                <xsl:apply-templates select="additional/*|someValue"/>
            </additional>
            <xsl:apply-templates select="node()[not(self::additional|self::someValue)]"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

使用此输入:

<root>
    <additional>
        <b>something</b>
    </additional>
    <someValue>123</someValue>
    <anotherValue>keep</anotherValue>
</root>

输出:

<root>
    <additional>
        <b>something</b>
        <someValue>123</someValue>
    </additional>
    <anotherValue>keep</anotherValue>
</root>

注意:只有一条规则可以覆盖身份转换。仅处理满足条件的rootsomeValueadditional个孩子)。复制root,将模板应用于属性(以进行进一步处理),并用additional元素包装将模板应用于additional的孩子和root的{​​{ 1}}个孩子。最后,将模板应用于someValueroot之外的additional的孩子。

答案 2 :(得分: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:strip-space elements="*"/>

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

<xsl:template match="/root/additional"/>

<xsl:template match="/root">
    <xsl:copy>
        <additional>
            <xsl:copy-of select="someValue"/>
            <xsl:copy-of select="additional/*"/>
        </additional>
    </xsl:copy>
</xsl:template>

这里我们剥离原始的附加,然后从头开始创建它,复制所需的 someValue 和源中的原始内容( additional / * )< / p>

答案 3 :(得分:-1)

用于版本 xslt 2.0

    <?xml version="1.0" encoding="UTF-8"?>
<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="xml" omit-xml-declaration="no" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node() except someValue"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="additional">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:copy-of select="following-sibling::someValue"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>