带命名空间的XSLT转换

时间:2016-11-14 11:17:54

标签: xml xslt

我需要一个简单的xslt,它接受输入并提供输出,如下所述。我编写了一个xslt,但命名空间被忽略了。你能帮帮我吗。

输入讯息:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ns2:esbMessage xmlns:ns2="http://messagev2.esb.company.com/">
        <header>
            <identity/>
            <message-id>56b3b200-1945-44a9-9dcf-a90de1f99060</message-id>
            <correlation-id>56b3b200-1945-44a9-9dcf-a90de1f99060</correlation-id>
            <message-date-time>2016-11-14T11:31:49</message-date-time>
            <esb-environment>DEV</esb-environment>
        </header>
        <errors/>
        <body>
            <urn:submitOrder xmlns:urn="urn:switchyard-quickstart:bean-service:1.0">
                <order>
                    <orderId>100001</orderId>
                    <itemId>5001</itemId>
                    <quantity>5</quantity>
                </order>
            </urn:submitOrder>
        </body>
    </ns2:esbMessage>

预期输出消息:

    <urn:submitOrder xmlns:urn="urn:switchyard-quickstart:bean-service:1.0">
                <order>
                    <orderId>100001</orderId>
                    <itemId>5001</itemId>
                    <quantity>5</quantity>
                </order>
    </urn:submitOrder>

实际输出消息:

 <submitOrder>
                <order>
                      <orderId>100001</orderId>
                      <itemId>5001</itemId>
                      <quantity>5</quantity>
                </order>
   </submitOrder>

XSLT:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml" encoding="utf-8"
        omit-xml-declaration="yes" />
    <xsl:template match="/">
                <xsl:for-each select="//body">
                    <xsl:apply-templates select="@* | node()" />
                </xsl:for-each>
    </xsl:template>

    <!-- template to copy elements -->
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:template>

    <!-- template to copy attributes -->
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}"  >
            <xsl:value-of select="." />
        </xsl:attribute>
    </xsl:template>

    <!-- template to copy the rest of the nodes -->
    <xsl:template match="comment() | text() | processing-instruction()">
        <xsl:copy />
    </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:2)

<强>予。更改了XML

<ns2:esbMessage xmlns:ns2="http://messagev2.esb.company.com/">
    <header>
        <identity/>
        <message-id>56b3b200-1945-44a9-9dcf-a90de1f99060</message-id>
        <correlation-id>56b3b200-1945-44a9-9dcf-a90de1f99060</correlation-id>
        <message-date-time>2016-11-14T11:31:49</message-date-time>
        <esb-environment>DEV</esb-environment>
    </header>
    <errors/>
    <body>
        <urn:submitOrder xmlns:urn="urn:switchyard-quickstart:bean-service:1.0">
            <!-- first -->
            <order>
                <orderId>100001</orderId>
                <itemId>5001</itemId>
                <quantity>5</quantity>
            </order>
            <?world?>
        </urn:submitOrder>
    </body>
</ns2:esbMessage>

<强> II。建议使用XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ns2="http://messagev2.esb.company.com/"
  xmlns:urn="urn:switchyard-quickstart:bean-service:1.0"
  exclude-result-prefixes="ns2">

  <xsl:output method="xml" indent="no" omit-xml-declaration="yes" />

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

  <xsl:template match="/">
    <xsl:apply-templates select="/ns2:esbMessage/body/urn:submitOrder"/>
  </xsl:template>

</xsl:stylesheet>

<强> III。结果

<urn:submitOrder xmlns:urn="urn:switchyard-quickstart:bean-service:1.0"
    xmlns:ns2="http://messagev2.esb.company.com/">
    <!-- first -->
    <order>
        <orderId>100001</orderId>
        <itemId>5001</itemId>
        <quantity>5</quantity>
    </order>
    <?world?>
</urn:submitOrder>

反馈给您的xslt:

您正在删除节点的命名空间,我认为您不了解您到目前为止所执行的操作。 local-name()仅返回节点的名称。在xslt中,您将使用源节点的本地名称创建一个新节点。

编辑1:

  

从结果中删除ns2

TBH与你,我不知道为什么上面的xslt将未使用的命名空间复制到输出xml。一种解决方案是:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:urn="urn:switchyard-quickstart:bean-service:1.0"
  xmlns:ns2="http://messagev2.esb.company.com/">

  <xsl:output method="xml" indent="no" omit-xml-declaration="yes" />

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

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

  <xsl:template match="/">
    <xsl:apply-templates select="/ns2:esbMessage/body/urn:submitOrder"/>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

实现所需结果的简单方法是:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:urn="urn:switchyard-quickstart:bean-service:1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/*">
    <xsl:copy-of select="body/urn:submitOrder"/>
</xsl:template>

</xsl:stylesheet>

结果:

<?xml version="1.0" encoding="UTF-8"?>
<urn:submitOrder xmlns:urn="urn:switchyard-quickstart:bean-service:1.0" xmlns:ns2="http://messagev2.esb.company.com/">
  <order>
    <orderId>100001</orderId>
    <itemId>5001</itemId>
    <quantity>5</quantity>
  </order>
</urn:submitOrder>

包含冗余的xmlns:ns2="http://messagev2.esb.company.com/"命名空间声明,您不必担心。如果删除它很重要(虽然我不明白为什么),你可以这样做:

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="*"/>

<xsl:template match="/*">
    <urn:submitOrder xmlns:urn="urn:switchyard-quickstart:bean-service:1.0">
        <xsl:apply-templates select="body/urn:submitOrder/order"/>
    </urn:submitOrder>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="{name()}">
        <xsl:apply-templates />
    </xsl:element>
</xsl:template>

</xsl:stylesheet>