【问题标题】:How to move Specific XML element using XSLT如何使用 XSLT 移动特定的 XML 元素
【发布时间】:2016-08-10 04:41:23
【问题描述】:

我正在尝试使用 XSL 文件将 XML 属性的特定元素移动到特定位置。

假设我有 XML

<all>
    <one>Something 1</one>
    <check>
        <present>
            <target> Hello </target>
            <abc> ABC </abc>
        </present>
        <absent> 
            <target> Hi </target>
            <pqr> PQR </pqr>
        </absent>
    </check>
    <action>
        <perform>
            <one>One</one>
            <two>Two</two>
        </perform>
    </action>
</all>

我想要这样的输出:

<all>
    <one>Something 1</one>
    <check>
        <present>
                     <abc> ABC </abc>
        </present>
        <absent> 
            <target> Hi </target>
            <pqr> PQR </pqr>
        </absent>
    </check>
    <action>
        <perform>
            <one>One</one>
            <two>Two</two>
            <target> Hello </target>
        </perform>
    </action>
</all>

为此我写了

       <xsl:template match= "@*|node()" >
    <xsl:copy>
        <xsl:apply-templates select= "@*|node()" />
    </xsl:copy>
</xsl:template >
 <xsl:template match= "action" >
        <xsl:copy>
            <xsl:apply-templates select= "@*|node()" />
            <xsl:apply-templates select= "../check/present/target" mode= "move" />
        </xsl:copy>
    </xsl:template >
<xsl:template match="target" mode="move">
     <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>
</xsl:template>

&lt;target&gt;Hello&lt;/target&gt; 移动到 &lt;action&gt; 下,但我希望它移动到 &lt;perform&gt; 内部 &lt;action&gt; 内部

【问题讨论】:

  • 你也有mode="move"的模板匹配目标吗?
  • 好吧,应用一个不存在的模板不会做任何事情。请参阅此处的示例:stackoverflow.com/questions/38650232/… 请注意,如果您不对“已移动”节点进行任何更改,则可以使用 xsl:copy
  • @michael.hor257k 我更新了我的 xsl 现在我有一个模板匹配目标与 mode="move"
  • 它完成了&lt;xsl:apply-templates select= "../../check/present/target" mode= "move" /&gt;

标签: xml xslt xslt-1.0


【解决方案1】:

如果要将target 节点放在perform 下,只需将模板匹配更改为匹配perform 而不是action

<xsl:template match="action/perform">

甚至这个(如果perform 只能在action 之下)

<xsl:template match="perform">

此外,由于您实际上并没有移动节点,而是添加一个新节点并删除现有节点,因此您还需要一个模板来忽略当前的 target 节点

<xsl:template match="present/target" />

试试这个 XSLT。请注意我如何将标识模板设为命名模板以避免一些代码重复。

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

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

    <xsl:template match="present/target" />

    <xsl:template match="action/perform">
        <xsl:copy>
            <xsl:apply-templates select= "@*|node()" />
            <xsl:apply-templates select= "../../check/present/target" mode="move" />
        </xsl:copy>
    </xsl:template >

    <xsl:template match="target" mode="move">
        <xsl:call-template name="identity" />
    </xsl:template>
</xsl:stylesheet>

当然,如果你不打算修改target元素,你可以直接使用xsl:copy-of

也试试这个

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

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

    <xsl:template match="present/target" />

    <xsl:template match="perform">
        <xsl:copy>
            <xsl:apply-templates select= "@*|node()" />
            <xsl:copy-of select= "../../check/present/target" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

【讨论】:

    猜你喜欢
    • 2018-05-12
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-03
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    相关资源
    最近更新 更多