Xml 使用xslt删除命名空间声明

Xml 使用xslt删除命名空间声明,xml,xslt,ibm-datapower,Xml,Xslt,Ibm Datapower,我的要求是,如果某些条件为真,则使用xslt从输入xml中删除名称空间声明 我在stackoverflow中浏览了各种论坛,之后我成功地构建了xsl,但它仍然不起作用。我对xsl非常陌生,因此需要这里的帮助来实现这一点 输入xml(出现名称空间声明) 我尝试了以下xslt: <?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://w

我的要求是,如果某些条件为真,则使用xslt从输入xml中删除名称空间声明

我在stackoverflow中浏览了各种论坛,之后我成功地构建了xsl,但它仍然不起作用。我对xsl非常陌生,因此需要这里的帮助来实现这一点

输入xml(出现名称空间声明)

我尝试了以下xslt:

     <?xml version="1.0" encoding="UTF-8" ?> 
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" extension-element-prefixes="dp" exclude-result-prefixes="dp">
          <xsl:output method="xml" indent="yes" version="1.0" /> 
         <xsl:variable name="origo-svc-augmented" select="'Y'"/>  
      <xsl:variable name="origo-svc-ns" select="'http://www.origoservices.com'" /> 
      <xsl:template match="*">
        <xsl:variable name="namespace" select="namespace-uri(.)" /> 
          <xsl:choose>
              <!-- 
          xsl:when test="$namespace = ''
                  or ($origo-svc-augmented='Y' and $namespace=$origo-svc-ns)"

         --> 
               <xsl:when test="$origo-svc-augmented = 'Y'">
                   <xsl:message dp:type="business-log" dp:priority="info">Namespace was augmented in the request rule</xsl:message> 
                <!-- Note: If we use "local-name()" instead of "name()" in below statement, then namespace prefixes will not be preserved. Using name(), will preserve the namespace prefixes
                  --> 
             <!-- xsl:element name="{name()} namespace="{$namespace}"
          --> 
                  <xsl:element name="{name()}">
               <xsl:copy-of select="namespace::*[not(namespace-uri()=$origo-svc-ns)]" /> 
               <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()" /> 
               </xsl:element>
              </xsl:when>
           <xsl:otherwise>
         <xsl:element name="{name()}" namespace="{$namespace}">
        <xsl:copy-of select="namespace::*" /> 
          <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()" /> 
        </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
       </xsl:template>
     <xsl:template match="@*|comment()|processing-instruction()|text()">
   <xsl:copy>
     <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()" /> 
      </xsl:copy>
     </xsl:template>
   </xsl:stylesheet>

命名空间在请求规则中得到了扩充
更新

我已经尝试将这两个答案结合起来,并能够找到解决方案。请在下面找到可用的XSLT

       <?xml version="1.0" encoding="UTF-8"?>
       <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" extension-element-prefixes="dp" exclude-result-prefixes="dp">
       <xsl:output method="xml" indent="yes" version="1.0"/>

       <xsl:variable name="origo-svc-augmented" select="'Y'"/>
       <xsl:variable name="origo-svc-ns" select="'http://www.origoservices.com'"/>

      <xsl:template match="*">
        <xsl:variable name="namespace" select="namespace-uri(.)"/>
         <xsl:choose>
           <xsl:when test="($origo-svc-augmented = 'Y') and (namespace-uri() = $origo-svc-ns)">
            <xsl:message dp:type="business-log" dp:priority="info">Namespace was augmented in the request rule</xsl:message>
             <xsl:element name="{local-name()}">
            <xsl:copy-of select="namespace::*[.!='http://www.origoservices.com']"/>
              <xsl:apply-templates
                select="@* | node() | comment() | processing-instruction() | text()"/>
        </xsl:element>
         </xsl:when>
          <xsl:otherwise>
             <xsl:element name="{name()}" namespace="{$namespace}">
            <xsl:copy-of select="namespace::*"/>
            <xsl:apply-templates
                select="@* | node() | comment() | processing-instruction() | text()"/>
        </xsl:element>
        </xsl:otherwise>
        </xsl:choose>
        </xsl:template>
      </xsl:stylesheet>

命名空间在请求规则中得到了扩充

如果我猜对了,您希望执行以下操作:

XSLT1.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:param name="no-namespace" select="false()"/>

<xsl:template match="*">
    <xsl:choose>
        <xsl:when test="$no-namespace">
            <xsl:element name="{local-name()}">
                <xsl:copy-of select="namespace::*[.!='http://www.origoservices.com']"/>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy>
                <xsl:copy-of select="namespace::*[.!='http://www.origoservices.com']"/>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates/>
            </xsl:copy>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>
如果
no namespace
参数为false,则结果将是输入的相同副本


注意:


根据所使用的特定XSLT处理器的不同,实际结果可能会有所不同。命名空间声明
xmlns:ds=”http://www.w3.org/2000/09/xmldsig#“
不在任何地方使用,因此是多余的。您不能真正强制XSLT1.0处理器输出冗余名称空间声明。上述结果对于Saxon 6.5和libxslt是正确的,但Xalan将忽略复制名称空间的指令,并且冗余名称空间将被抑制。

如果我猜对了,您希望执行以下操作:

XSLT1.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:param name="no-namespace" select="false()"/>

<xsl:template match="*">
    <xsl:choose>
        <xsl:when test="$no-namespace">
            <xsl:element name="{local-name()}">
                <xsl:copy-of select="namespace::*[.!='http://www.origoservices.com']"/>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy>
                <xsl:copy-of select="namespace::*[.!='http://www.origoservices.com']"/>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates/>
            </xsl:copy>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>
如果
no namespace
参数为false,则结果将是输入的相同副本


注意:


根据所使用的特定XSLT处理器的不同,实际结果可能会有所不同。命名空间声明
xmlns:ds=”http://www.w3.org/2000/09/xmldsig#“
不在任何地方使用,因此是多余的。您不能真正强制XSLT1.0处理器输出冗余名称空间声明。上述结果对于Saxon 6.5和libxslt是正确的,但Xalan将忽略复制名称空间的指令,冗余名称空间将被抑制。

假设您只想删除与
http://www.origoservices.com
URI,我会将命名空间删除的条件更改为:

 <xsl:when test="($origo-svc-augmented = 'Y') and (namespace-uri() = $origo-svc-ns)">

然后像这样输出元素,以避免复制名称空间:

<xsl:element name="{local-name()}">

使用
复制命名空间节点将变得无用,您可以将其删除

然后,您将得到以下模板:

<xsl:template match="*">
    <xsl:variable name="namespace" select="namespace-uri(.)"/>
    <xsl:choose>
        <xsl:when test="($origo-svc-augmented = 'Y') and (namespace-uri() = $origo-svc-ns)">
            <xsl:message dp:type="business-log" dp:priority="info">Namespace was augmented in the request rule</xsl:message>
            <xsl:element name="{local-name()}">
                <xsl:apply-templates
                    select="@* | node() | comment() | processing-instruction() | text()"/>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="{name()}" namespace="{$namespace}">
                <xsl:copy-of select="namespace::*"/>
                <xsl:apply-templates
                    select="@* | node() | comment() | processing-instruction() | text()"/>
            </xsl:element>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

命名空间在请求规则中得到了扩充
这是获得的结果XML:

<?xml version="1.0" encoding="UTF-8"?>
<message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.origoservices.com CEBondRealTimeValuationResponse.XSD">
    <m_control>
        <control_timestamp>2015-11-18T12:15:00</control_timestamp>
        <message_id>428f7945-a3d8-49f8-ada3-b6e898ace9fe</message_id>
        <retry_number>0</retry_number>
        <message_type>test</message_type>
        <message_version>test</message_version>
        <message_status>Success</message_status>
        <expected_response_type>synchronous</expected_response_type>
        <initiator_id>Testing</initiator_id>
        <responder_id>Test-comp</responder_id>
    </m_control>
    <m_content>
        <b_control>
            <contract_enquiry_reference/>
            <enquiry_response_status>Error</enquiry_response_status>
            <enquiry_error_note code="1005" sequence_number="1">
                <short_description>Contract not found.</short_description>
            </enquiry_error_note>
        </b_control>
        <intermediary/>
        <request_scope>
            <valuation_request type="Current"/>
            <valuation_request type="Surrender"/>
            <fund_breakdown_request>
                <detailed_breakdown_ind>Yes</detailed_breakdown_ind>
            </fund_breakdown_request>
        </request_scope>
        <contract>
            <contract_reference_number>20015</contract_reference_number>
        </contract>
    </m_content>
</message>

2015-11-18T12:15:00
428f7945-a3d8-49f8-ada3-b6e898ace9fe
0
测试
测试
成功
同步的
测试
测试公司
错误
未找到合同。
对
20015

因为名称空间
xmlns:ds=”http://www.w3.org/2000/09/xmldsig#“
从未在您的输入XML文档中使用过,它不会被输出。

假设您只想删除与
相关的命名空间http://www.origoservices.com
URI,我会将命名空间删除的条件更改为:

 <xsl:when test="($origo-svc-augmented = 'Y') and (namespace-uri() = $origo-svc-ns)">

然后像这样输出元素,以避免复制名称空间:

<xsl:element name="{local-name()}">

使用
复制命名空间节点将变得无用,您可以将其删除

然后,您将得到以下模板:

<xsl:template match="*">
    <xsl:variable name="namespace" select="namespace-uri(.)"/>
    <xsl:choose>
        <xsl:when test="($origo-svc-augmented = 'Y') and (namespace-uri() = $origo-svc-ns)">
            <xsl:message dp:type="business-log" dp:priority="info">Namespace was augmented in the request rule</xsl:message>
            <xsl:element name="{local-name()}">
                <xsl:apply-templates
                    select="@* | node() | comment() | processing-instruction() | text()"/>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="{name()}" namespace="{$namespace}">
                <xsl:copy-of select="namespace::*"/>
                <xsl:apply-templates
                    select="@* | node() | comment() | processing-instruction() | text()"/>
            </xsl:element>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

命名空间在请求规则中得到了扩充
这是获得的结果XML:

<?xml version="1.0" encoding="UTF-8"?>
<message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.origoservices.com CEBondRealTimeValuationResponse.XSD">
    <m_control>
        <control_timestamp>2015-11-18T12:15:00</control_timestamp>
        <message_id>428f7945-a3d8-49f8-ada3-b6e898ace9fe</message_id>
        <retry_number>0</retry_number>
        <message_type>test</message_type>
        <message_version>test</message_version>
        <message_status>Success</message_status>
        <expected_response_type>synchronous</expected_response_type>
        <initiator_id>Testing</initiator_id>
        <responder_id>Test-comp</responder_id>
    </m_control>
    <m_content>
        <b_control>
            <contract_enquiry_reference/>
            <enquiry_response_status>Error</enquiry_response_status>
            <enquiry_error_note code="1005" sequence_number="1">
                <short_description>Contract not found.</short_description>
            </enquiry_error_note>
        </b_control>
        <intermediary/>
        <request_scope>
            <valuation_request type="Current"/>
            <valuation_request type="Surrender"/>
            <fund_breakdown_request>
                <detailed_breakdown_ind>Yes</detailed_breakdown_ind>
            </fund_breakdown_request>
        </request_scope>
        <contract>
            <contract_reference_number>20015</contract_reference_number>
        </contract>
    </m_content>
</message>

2015-11-18T12:15:00
428f7945-a3d8-49f8-ada3-b6e898ace9fe
0
测试
测试
成功
同步的
测试
测试公司
错误
未找到合同。
对
20015

因为名称空间
xmlns:ds=”http://www.w3.org/2000/09/xmldsig#“
从未在您的输入XML文档中使用,它不会被输出。

重要的是要理解,在XDM数据模型方面,您所做的不是删除名称空间,而是更改元素的名称

除非元素或属性的内容中出现了qname(或名称空间前缀)(与其名称相反),否则不必担心使用名称空间轴或生成名称空间节点。只要用正确的名称(我指的是名称空间URI加上本地名称)生成元素和属性,名称空间声明就会自行处理

xsl:copy
指令应用于元素时,复制