删除 Soap 标头和命名空间

Posted

技术标签:

【中文标题】删除 Soap 标头和命名空间【英文标题】:Remove Soap Headers and Namespaces 【发布时间】:2021-09-07 15:19:03 【问题描述】:

我有一个要求,我需要从 XML 中删除 SOAP 标头和所有命名空间。我在网上搜索过,我有 2 个单独的 XSLT,一个用于删除 SOAP 标头,另一个用于删除命名空间。我们可以使用一个 XSLT 来执行这两个操作吗?

提前致谢!

XML:

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
    <soap-env:Header>
        <n0:Info xmlns:n0="http://www.sap.com/dfg">
            <m:Type xmlns:m="http://www.sap.com/dfg">SA</m:Type>
            <m:App xmlns:m="http://www.sap.com/fghj"/>
            <m:Component xmlns:m="http://www.sap.com/tghj"/>
        </n0:Info>
    </soap-env:Header>
    <soap-env:Body>
        <n1:data xmlns:n1="http://namspace.com" xmlns:prx="urn:sap.com:proxy:XXXX">
            <n1:dataSegement>
                <n1:dataSegementKey>12345678</n1:dataSegementKey>
                <n1:number>123456789</n1:number>
                <n1:dueDate>01/06/2021</n1:dueDate>
                <n1:amount>1200.0000</n1:amount>
            </n1:dataSegement>
            <n1:dataSegement>
                <n1:dataSegementKey>123456789</n1:dataSegementKey>
                <n1:number>12345678</n1:number>
                <n1:dueDate>28/05/2021</n1:dueDate>
                <n1:amount>-1746.4000</n1:amount>
            </n1:dataSegement>
        </n1:data>
    </soap-env:Body>
</soap-env:Envelope>

用于删除 SOAP 标头的 XLST:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" version="1.0">
   <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
   <xsl:template match="/">
      <xsl:copy-of select="SOAP-ENV:Envelope/SOAP-ENV:Body/*" />
   </xsl:template>
</xsl:stylesheet>

用于删除命名空间的 XLST:

<?xml version="1.0"?>
<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"/>

    <!-- Stylesheet to remove all namespaces from a document -->
    <!-- NOTE: this will lead to attribute name ***, if an element contains
        two attributes with same local name but different namespace prefix -->
    <!-- Nodes that cannot have a namespace are copied as such -->

    <!-- 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>

预期输出:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <dataSegement>
        <dataSegementKey>12345678</dataSegementKey>
        <number>123456789</number>
        <dueDate>01/06/2021</dueDate>
        <amount>1200.0000</amount>
    </dataSegement>
    <dataSegement>
        <dataSegementKey>123456789</dataSegementKey>
        <number>12345678</number>
        <dueDate>28/05/2021</dueDate>
        <amount>-1746.4000</amount>
    </dataSegement>
</data>

【问题讨论】:

【参考方案1】:

使用以下样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:n1="http://namspace.com">
    <xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="no"/>

    <!-- Stylesheet to remove all namespaces from a document -->
    <!-- NOTE: this will lead to attribute name ***, if an element contains
        two attributes with same local name but different namespace prefix -->
    <!-- Nodes that cannot have a namespace are copied as such -->

    <!-- template to copy all attributes and 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="/soap-env:*">
      <xsl:apply-templates select="soap-env:Body/n1:data" />
    </xsl:template>

</xsl:stylesheet>

输出是:

<?xml version="1.0" encoding="utf-8"?>
<data>
   <dataSegement>
      <dataSegementKey>12345678</dataSegementKey>
      <number>123456789</number>
      <dueDate>01/06/2021</dueDate>
      <amount>1200.0000</amount>
   </dataSegement>
   <dataSegement>
      <dataSegementKey>123456789</dataSegementKey>
      <number>12345678</number>
      <dueDate>28/05/2021</dueDate>
      <amount>-1746.4000</amount>
   </dataSegement>
</data>

【讨论】:

以上是关于删除 Soap 标头和命名空间的主要内容,如果未能解决你的问题,请参考以下文章

WCF - Soap 标头在安全元素中引用命名空间两次

如何删除Zend_Soap中的命名空间?

如果命名空间声明在 SOAP 信封上,如何使用 JAXB 解组 SOAP 响应?

命名空间删除xml

我对 SOAP 命名空间感到困惑

使用 XLS 删除一些命名空间前缀