使用xslt替换xml节点

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

在这个xml中,我想用另一个节点<transfom>替换<message>节点,但是复制数据。

是否可以使用xslt,我使用xslt 2.0将转换节点转换为消息节点,但它仅适用于一个流节点。

<root
    xmlns="http://www.example.com/something">
    <flow>
        <list name="listName"/>
        <router name="router"/>
        <!-- I have some other tags here -->
    </flow>
    <flow>
        <list name="listName"/>
        <console name="console"/>
        <!-- I have some other tags here -->
    </flow>
    <flow>
        <payload name="example"/>
        <transform name="transform">
            <!-- Some DATA here --->
        </transform>
        <!-- I have some other tags here -->
    </flow>
    <flow>
        <payload name="sada"/>
        <transform name="transform1">
            <!-- Some DATA here --->
        </transform>
        <!-- I have some other tags here -->
        <transform name="transform2">
            <!-- Some DATA here --->
        </transform>
    </flow>
</root>

<transform>节点存在于两个<flow>节点中。有没有办法编写通用的XSLT,用<transform>节点替换<message>,保持节点的位置和节点内的数据。

我使用过<xsl:for-each><xsl:when>以及xpath表达式,例如前面的,后面的。但它们只转换<transform name="transform node">,但按原样复制所有其他xml节点。请让我知道如何解决这个问题!


更新

这是我用来转换xml的样式表

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <root>
        <xsl:for-each select="flow">
            <xsl:choose>
                <xsl:when test="descendant-or-self::transform">
                    <message>
                        <xsl:attribute name="doc:name">
                            <xsl:value-of
                                        select="//transform/@name" />
                        </xsl:attribute>
                        <ee:message>
                            <ee:set-payload>
                                <xsl:value-of select="payload" />
                            </ee:set-payload>
                        </ee:message>
                    </ee:transform>
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </root>
</xsl:stylesheet>

更新14/04/2019

如何从<root>标签更改名称空间?转换时我有一堆名称空间要改变。怎么做?

java xml xslt
1个回答
0
投票

转换设计应该从身份转换开始(参见https://www.w3.org/TR/xslt20/#element-copy中的“示例:身份转换”一节),然后只为要转换的节点添加模板,在XSLT 3中,您可以将身份转换声明为默认处理使用<xsl:mode on-no-match="shallow-copy"/>https://www.w3.org/TR/xslt-30/#built-in-templates-shallow-copy)然后你只需要为transform元素写一个模板:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xpath-default-namespace="http://www.example.com/something"
    xmlns="http://www.example.com/something"
    exclude-result-prefixes="#all"
    version="3.0">

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

  <xsl:template match="flow/transform">
      <message>
          <xsl:apply-templates select="@*, node()"/>
      </message>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/pPzifpw

在XSLT 2中你必须拼写出来:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xpath-default-namespace="http://www.example.com/something"
    xmlns="http://www.example.com/something"
    exclude-result-prefixes="#all"
    version="2.0">

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

  <xsl:template match="flow/transform">
      <message>
          <xsl:apply-templates select="@*, node()"/>
      </message>
  </xsl:template>

</xsl:stylesheet>
© www.soinside.com 2019 - 2024. All rights reserved.