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

Posted

技术标签:

【中文标题】使用 XLS 删除一些命名空间前缀【英文标题】:Remove some namespace prefixes with XLS 【发布时间】:2020-04-05 10:11:09 【问题描述】:

这是我的 XML

<soapenv:Envelope xmlns:ns="urn:sap-com:document:sap:rfc:functions" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <ns:BAPI_PRODORD_GET_LIST>
         <ns:ORDER_NUMBER_RANGE>
            <ns:Item>
               <ns:SIGN>I</ns:SIGN>
               <ns:OPTION>EQ</ns:OPTION>
               <ns:LOW>150000033760</ns:LOW>
               <ns:HIGH>150000033765</ns:HIGH>
            </ns:Item>
         </ns:ORDER_NUMBER_RANGE>
         <ns:PLANPLANT_RANGE>
            <ns:Item>
               <ns:SIGN>I</ns:SIGN>
               <ns:OPTION>EQ</ns:OPTION>
               <ns:LOW>TM04</ns:LOW>
            </ns:Item>
         </ns:PLANPLANT_RANGE>
      </ns:BAPI_PRODORD_GET_LIST>
   </soapenv:Body>
</soapenv:Envelope>

我需要这个:

<soapenv:Envelope xmlns:ns="urn:sap-com:document:sap:rfc:functions" 
            xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <ns:BAPI_PRODORD_GET_LIST>
         <ORDER_NUMBER_RANGE>
            <item>
               <SIGN>I</SIGN>
               <OPTION>EQ</OPTION>
               <LOW>150000033760</LOW>
               <HIGH>150000033765</HIGH>
            </item>
         </ORDER_NUMBER_RANGE>
         <PLANPLANT_RANGE>
            <item>
               <SIGN>I</SIGN>
               <OPTION>EQ</OPTION>
               <LOW>TM04</LOW>
            </item>
         </PLANPLANT_RANGE>
      </ns:BAPI_PRODORD_GET_LIST>
   </soapenv:Body>
</soapenv:Envelope>

我尝试使用此 XSLT,但删除所有前缀和命名空间:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:template match="/">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>
<xsl:template match="@*">
    <xsl:attribute name="local-name()">
        <xsl:value-of select="current()"/>
    </xsl:attribute>
</xsl:template>
<xsl:template match="*">
    <xsl:element name="local-name()">
        <xsl:apply-templates select="@* | * | text()"/>
    </xsl:element>
</xsl:template>
<xsl:template match="text()">
    <xsl:copy>
        <xsl:value-of select="current()"/>
    </xsl:copy>
</xsl:template>
    <xsl:template match="Envelope/Body">
        <soapenv:Body><xsl:apply-templates select="@*|node()" /></soapenv:Body>
    </xsl:template>
</xsl:stylesheet>

这个结果是这样的:

<Envelope>
   <Header/>
   <Body>
      <BAPI_PRODORD_GET_LIST>
         <ORDER_NUMBER_RANGE>
            <Item>
               <SIGN>I</SIGN>
               <OPTION>EQ</OPTION>
               <LOW>150000033760</LOW>
               <HIGH>150000033765</HIGH>
            </Item>
         </ORDER_NUMBER_RANGE>
         <PLANPLANT_RANGE>
            <Item>
               <SIGN>I</SIGN>
               <OPTION>EQ</OPTION>
               <LOW>TM04</LOW>
            </Item>
         </PLANPLANT_RANGE>
      </BAPI_PRODORD_GET_LIST>
   </Body>
</Envelope>

我需要删除ns:BAPI_PRODORD_GET_LIST 中的所有命名空间

<ns:BAPI_PRODORD_GET_LIST>
<ns:ORDER_NUMBER_RANGE>
<ns:Item>
<ns:SIGN>I</ns:SIGN>
...
</ns:BAPI_PRODORD_GET_LIST>

其余的必须保持不变。

【问题讨论】:

【参考方案1】:

这个样式表

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns="urn:sap-com:document:sap:rfc:functions">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="ns:*//@*">
        <xsl:attribute name="local-name()">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    <xsl:template match="ns:*//*">
        <xsl:element name="local-name()">
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

输出:

<soapenv:Envelope xmlns:ns="urn:sap-com:document:sap:rfc:functions"
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <ns:BAPI_PRODORD_GET_LIST>
         <ORDER_NUMBER_RANGE>
            <Item>
               <SIGN>I</SIGN>
               <OPTION>EQ</OPTION>
               <LOW>150000033760</LOW>
               <HIGH>150000033765</HIGH>
            </Item>
         </ORDER_NUMBER_RANGE>
         <PLANPLANT_RANGE>
            <Item>
               <SIGN>I</SIGN>
               <OPTION>EQ</OPTION>
               <LOW>TM04</LOW>
            </Item>
         </PLANPLANT_RANGE>
      </ns:BAPI_PRODORD_GET_LIST>
   </soapenv:Body>
</soapenv:Envelope>

这使用“覆盖身份规则”模式。

【讨论】:

以上是关于使用 XLS 删除一些命名空间前缀的主要内容,如果未能解决你的问题,请参考以下文章

XSL:删除命名空间前缀

在 JAXB 编组时删除命名空间前缀

XSLT - 删除前缀命名空间特定节点 XML

首选命名空间前缀列表?

重命名元素的 XSLT 问题——更改命名空间

如何用前缀替换 xmlns 命名空间属性?