有条件地使用xslt添加默认名称空间 [英] Adding default namespace conditionally using xslt

查看:75
本文介绍了有条件地使用xslt添加默认名称空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要求:

  • 检查请求xml中是否存在默认名称空间声明xmlns="http://www.origoservices.com.

如果没有,请添加默认的名称空间声明.

If not, add the default namespace declaration.

样品请求xml 1:

<message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<m_control>
        <control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
        <retry_number>0</retry_number>
        <expected_response_type>synchronous</expected_response_type>
        <responder_id>Exchange Life 1</responder_id>
</m_control>
</message>

预期输出:

   <message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.origoservices.com">
<m_control>
         <control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
          <retry_number>0</retry_number>
    <expected_response_type>synchronous</expected_response_type>
    <responder_id>Exchange Life 1</responder_id>
</m_control>
</message>

样本请求xml 2

  <message>
<m_control>
    <control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
        <retry_number>0</retry_number>
    <expected_response_type>synchronous</expected_response_type>
    <responder_id>Exchange Life 1</responder_id>
</m_control>
</message>

预期产量

   <message xmlns="http://www.origoservices.com">
<m_control>
    <control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
        <retry_number>0</retry_number>
    <expected_response_type>synchronous</expected_response_type>
    <responder_id>Exchange Life 1</responder_id>
</m_control>
</message>

样本请求xml 3

<message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.origoservices.com">
<m_control>
    <control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
        <retry_number>0</retry_number>
    <expected_response_type>synchronous</expected_response_type>
    <responder_id>Exchange Life 1</responder_id>
</m_control>
</message>

预期的输出:这应该与输入相同,因为已经声明了默认的名称空间.

Expected output : This should be same as input as it already has default namespace declared.

<message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.origoservices.com">
<m_control>
    <control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
        <retry_number>0</retry_number>
    <expected_response_type>synchronous</expected_response_type>
    <responder_id>Exchange Life 1</responder_id>
</m_control>
</message>

我在xslt之下尝试过,但是不确定如何添加条件以检查请求xml中是否存在默认名称空间声明.

I have tried below xslt, but not sure how to add the condition to check the existence of the default namespace declaration in the request xml.

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

   <!-- Below statements will copy all the elements and attributes from source to destination, normally this will copy over the element and attributes tags to destination-->

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

  <xsl:template match="/*">
  <message xmlns="http://www.origoservices.com">
  <!--below statement will copy all the existing namespace declaration from source to destination-->
  <xsl:copy-of select="namespace::*" />
  <!--below statement will copy all the elements and attributes within the message root element to the resulting doc -->
  <xsl:apply-templates select="@*|node()" />
  </message>
</xsl:template>

更新 下面的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" xmlns:regexp="http://exslt.org/regular-expressions" extension-element-prefixes="dp" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="dp regexp exsl">

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

  <xsl:template match="/*[local-name()='message']">
 <!--xsl:template match="/message"-->
         <!--xsl:variable name="name" select="name(/*[1])"/-->
         <!--xsl:variable name="namespace-in" select="namespace-uri(/*[1])"/-->

         <xsl:variable name="name" select="name()"/>

         <!--Variable "namespace-in" will contain the namespace uri of the namspace of which message element is a part-->
         <!--As message element is a part of namespace having uri "http://www.origoservices.com", this value will be assigned to the variable -->
         <xsl:variable name="namespace-in" select="namespace-uri()"/>


                     <!--Set Variable which stores the default namespace URI. This step will also set a context variable  "AddNamespace"  with value "Y" -->       
         <xsl:variable name="namespace">
                  <xsl:choose>
                      <xsl:when test="$namespace-in = ''">
                              <xsl:value-of select="$origo-svc-ns"/>
                              <dp:set-variable name="'var://context/FL/AddNamspace'" value="Y"/>
                      </xsl:when>
                     <xsl:otherwise>
                              <xsl:value-of select="$namespace-in"/>
                     </xsl:otherwise>
                </xsl:choose>
      </xsl:variable>


       <!-- - In below statement, {$namespace} will copy over the default namespace declarartion to the destination.
            - copy-of select statement will copy over all the namespace declaration in the source xml 
            - apply-template will copy over evrything else from the source to destination
            - xsl:element will create an element node (in this case <message> ) in the destination document.      
      -->

    <xsl:element name="{$name}" namespace="{$namespace}">
  <xsl:copy-of select="namespace::*"/>
  <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
    <xsl:with-param name="ns-uri" select="$namespace"/>
  </xsl:apply-templates>
  </xsl:element>

  </xsl:template>

  <!--Above template only copy over the values of element,attributes,etc to the destination, below template copies the names of elements (only nodes) to the destination-->

   <xsl:template match="node()">
     <xsl:param name="ns-uri"/>
       <xsl:element name="{local-name()}" namespace="{$ns-uri}">
         <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
      <xsl:with-param name="ns-uri" select="$ns-uri"/>
       </xsl:apply-templates>
   </xsl:element>
    </xsl:template>

     <xsl:template match="@*|comment()|processing-instruction()|text()">
         <xsl:param name="ns-uri"/>
           <xsl:copy>
            <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
          <xsl:with-param name="ns-uri" select="$ns-uri"/>
         </xsl:apply-templates>
          </xsl:copy>
     </xsl:template>

   </xsl:stylesheet>

推荐答案

下面的xslt对我来说很好用.

The below xslt works fine for me.

  <?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" xmlns:regexp="http://exslt.org/regular-expressions" extension-element-prefixes="dp" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="dp regexp exsl">

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

      <xsl:template match="/*[local-name()='message']">
      <!--xsl:template match="/message"-->
     <!--xsl:variable name="name" select="name(/*[1])"/-->
     <!--xsl:variable name="namespace-in" select="namespace-uri(/*[1])"/-->

      <xsl:variable name="name" select="name()"/>

     <!--Variable "namespace-in" will contain the namespace uri of the namspace of which message element is a part-->
     <!--As message element is a part of namespace having uri "http://www.origoservices.com", this value will be assigned to the variable -->
      <xsl:variable name="namespace-in" select="namespace-uri()"/>


                 <!--Set Variable which stores the default namespace URI. This step will also set a context variable  "AddNamespace"  with value "Y" -->       
       <xsl:variable name="namespace">
              <xsl:choose>
                  <xsl:when test="$namespace-in = ''">
                          <xsl:value-of select="$origo-svc-ns"/>
                          <dp:set-variable name="'var://context/FL/AddNamspace'" value="Y"/>
                  </xsl:when>
                 <xsl:otherwise>
                          <xsl:value-of select="$namespace-in"/>
                 </xsl:otherwise>
            </xsl:choose>
     </xsl:variable>


   <!-- - In below statement, {$namespace} will copy over the default namespace declarartion to the destination.
        - copy-of select statement will copy over all the namespace declaration in the source xml 
        - apply-template will copy over evrything else from the source to destination
        - xsl:element will create an element node (in this case <message> ) in the destination document.      
  -->

   <xsl:element name="{$name}" namespace="{$namespace}">
   <xsl:copy-of select="namespace::*"/>
   <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
   <xsl:with-param name="ns-uri" select="$namespace"/>
   </xsl:apply-templates>
   </xsl:element>

   </xsl:template>

   <!--Above template only copy over the values of element,attributes,etc to the destination, below template copies the names of elements (only nodes) to the destination-->

   <xsl:template match="node()">
     <xsl:param name="ns-uri"/>
       <xsl:element name="{local-name()}" namespace="{$ns-uri}">
         <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
      <xsl:with-param name="ns-uri" select="$ns-uri"/>
     </xsl:apply-templates>
     </xsl:element>
     </xsl:template>

     <xsl:template match="@*|comment()|processing-instruction()|text()">
     <xsl:param name="ns-uri"/>
       <xsl:copy>
        <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
      <xsl:with-param name="ns-uri" select="$ns-uri"/>
     </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>

    </xsl:stylesheet>

这篇关于有条件地使用xslt添加默认名称空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆