首页 > 解决方案 > 使用 XSLT 重命名 XML 标记

问题描述

我想使用 xslt 重构 XML。在输入 XML 中也有 ?xml-multiple 标记。

输入

<?xml version="1.0" encoding="UTF-8"?>
<jsonObject>
<aaaa>
  <details>
     <name>abc</name>
  </details>
  <approved>true</approved>
</aaaa>
<payload>
  <NICNumber>
     <name>New</name>
     <address>
        <ffff>122</ffff>
        <gggg>true</gggg>
     </address>
     <gccid>1</gccid>
     <?xml-multiple NICNumberAlias?>
     <NICNumberAlias>
        <id>123</id>
     </NICNumberAlias>
     <?xml-multiple managersNICNumber?>
     <managersNICNumber>
        <userId>bbbbee</userId>
     </managersNICNumber>
  </NICNumber>
</payload>
</jsonObject>

XSLT

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

<xsl:template match="/">
    <jsonArray>
        <xsl:for-each select="jsonObject">
            <jsonObject>
                <xsl:apply-templates select="aaaa"/>
                <payload>
                    <xsl:copy-of select="payload/NICNumber/address" />
                    <xsl:apply-templates select="payload/NICNumber/address" />
                    <xsl:processing-instruction name="xml-multiple">NICNumbers</xsl:processing-instruction>
                    <NICNumbers>
                        <xsl:apply-templates select="payload/NICNumber/child::node()"/>
                    </NICNumbers>
                </payload>
            </jsonObject>
        </xsl:for-each>
    </jsonArray>
</xsl:template>

<xsl:template match="payload/NICNumber/address"/>

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

<xsl:template match="payload/NICNumber/managersNICNumber">
    <xsl:if test="count(../managersNICNumber)=1">
      <xsl:processing-instruction name="xml-multiple">xxxx</xsl:processing-instruction>
    </xsl:if>
    <xxxx>
        <xsl:apply-templates select="@*|node()" />
    </xxxx>
</xsl:template>


<xsl:template match="payload/NICNumber/NICNumberAlias">
    <xsl:if test="count(../NICNumberAlias)=1">
      <xsl:processing-instruction name="xml-multiple">NICNumberAliases</xsl:processing-instruction>
    </xsl:if>
    <NICNumberAliases>
        <xsl:apply-templates select="@*|node()" />
    </NICNumberAliases>
</xsl:template>

</xsl:stylesheet>

预期结果

<?xml version="1.0" encoding="UTF-8"?>
<jsonArray>
<jsonObject>
<aaaa>
    <details>
        <name>abc</name>
    </details>
    <approved>true</approved>
 </aaaa>
  <payload>
     <address>
        <ffff>122</ffff>
        <gggg>true</gggg>
     </address>
     <?xml-multiple NICNumbers?>
     <NICNumbers>
        <name>New</name>
        <gccid>1</gccid>
        <?xml-multiple NICNumberAliases?>
        <NICNumberAliases>
           <id>123</id>
        </NICNumberAliases>
        <?xml-multiple xxxx?>
        <xxxx>
           <userId>bbbbee</userId>
        </xxxx>
     </NICNumbers>
  </payload>
  </jsonObject>
  </jsonArray>

但我收到以下回复。

<?xml version="1.0" encoding="UTF-8"?>
<jsonArray>
<jsonObject>
  <aaaa>
    <details>
        <name>abc</name>
    </details>
    <approved>true</approved>
  </aaaa>
  <payload>
     <address>
        <ffff>122</ffff>
        <gggg>true</gggg>
     </address>
     <?xml-multiple NICNumbers?>
     <NICNumbers>
        <name>New</name>
        <gccid>1</gccid>
        <?xml-multiple NICNumberAlias?>
        <?xml-multiple NICNumberAliases?>
        <NICNumberAliases>
           <id>123</id>
        </NICNumberAliases>
        <?xml-multiple managersNICNumber?>
        <?xml-multiple xxxx?>
        <xxxx>
           <userId>bbbbee</userId>
        </xxxx>
     </NICNumbers>
  </payload>
 </jsonObject>
 </jsonArray>

从输入消息中,我将“managersNICNumber”的内容移动到 xxxx。managerNICNumber 已<?xml-multiple managersNICNumber?>在输入有效负载中。即使我将 managerNICNumber 移动到 xxxx,在从我的 XSLT 接收到的消息中<?xml-multiple managersNICNumber?>也包含。

我的 XSLT 有什么问题吗?

标签: xmlxslt

解决方案


我无法遵循您的 XSLT 的逻辑。AFAICT,可以使用以下方法产生所需的结果:

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:strip-space elements="*"/>

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

<!-- add wrapper  -->
<xsl:template match="/">
    <jsonArray>
        <xsl:apply-templates/>
    </jsonArray>
</xsl:template>

<xsl:template match="payload">
    <xsl:copy>
        <!-- move address to here -->
        <xsl:copy-of select="NICNumber/address" />
        <xsl:processing-instruction name="xml-multiple">NICNumbers</xsl:processing-instruction>
        <xsl:apply-templates select="NICNumber"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="NICNumber">
    <NICNumbers>
        <!-- remove address -->
        <xsl:apply-templates select="node()[not(self::address)]"/>
    </NICNumbers>
</xsl:template>

<!-- rename NICNumberAlias [1] -->
<xsl:template match="processing-instruction('xml-multiple')[.='NICNumberAlias']">
    <xsl:processing-instruction name="xml-multiple">NICNumberAliases</xsl:processing-instruction>
</xsl:template>

<!-- rename NICNumberAlias [2] -->
<xsl:template match="NICNumberAlias">
    <NICNumberAliases>
        <xsl:apply-templates/>
    </NICNumberAliases>
</xsl:template>

<!-- rename managersNICNumber [1] -->
<xsl:template match="processing-instruction('xml-multiple')[.='managersNICNumber']">
    <xsl:processing-instruction name="xml-multiple">xxxx</xsl:processing-instruction>
</xsl:template>

<!-- rename managersNICNumber [2] -->
<xsl:template match="managersNICNumber">
    <xxxx>
        <xsl:apply-templates/>
    </xxxx>
</xsl:template>

</xsl:stylesheet>

推荐阅读