English 中文(简体)
如何在肥皂申请中使用xsl改变名称空间
原标题:How to change namespace uri using xsl in soap request

我有这一请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"         xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<soapenv:Header>
    <wsse:Security mustUnderstand="1">
        <wsse:UsernameToken>
            <wsse:Username>test</wsse:Username>
            <wsse:Password>test</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>
<soapenv:Body>
  <hel:docTypeRef_tns_sayHello xmlns:hel="http://aaa/bbb.fr">
     <arg0>John</arg0>
     <arg1>111-222-333</arg1>
  </hel:docTypeRef_tns_sayHello>
</soapenv:Body>
</soapenv:Envelope>

I would like first to change the namespace uri appearing in the hel:docTypeRef_tns_sayHello element to something else (ex : http://test.fr). This namespace definition can appear in the hel:docTypeRef_tns_sayHello element as in the code above or in the root Envelope element, so i d like to add this namespace definition only in the Envelope element

然后,我要将必须理解的属性价值改为0。

其结果应为:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"       xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-    1.0.xsd" 
**xmlns:hel="http://test.fr"**>
<soapenv:Header>
    <wsse:Security mustUnderstand="**0**">
        <wsse:UsernameToken>
            <wsse:Username>test</wsse:Username>
            <wsse:Password>test</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>
<soapenv:Body>
  <hel:docTypeRef_tns_sayHello>
     <arg0>John</arg0>
     <arg1>111-222-333</arg1>
  </hel:docTypeRef_tns_sayHello>
</soapenv:Body>
</soapenv:Envelope>

Could somebody help me ? Thancks !

问题回答

<>I>。 此处为一种通用的参数XSLT1.0解决办法:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pElemName" select=" hel:docTypeRef_tns_sayHello "/>
 <xsl:param name="pOldNamespace" select=" http://aaa/bbb.fr "/>
 <xsl:param name="pNewNamespace" select=" http://test.fr "/>

 <xsl:variable name="vPrefix" select="substring-before($pElemName,  : )"/>

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

 <xsl:template match="*">
  <xsl:choose>
      <xsl:when test=
       "not(name() = $pElemName
          and
            namespace-uri() = $pOldNamespace
           )
       ">
        <xsl:call-template name="identity"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:element name="{name()}" namespace="{$pNewNamespace}">
         <xsl:copy-of select=
           "namespace::*
                 [not(name() = $vPrefix
                    and
                      . = $pOldNamespace
                      )
                ]"/>

         <xsl:apply-templates select="@*"/>

         <xsl:apply-templates select="node()" mode="removeNS"/>
        </xsl:element>
      </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

 <xsl:template match="*" mode="removeNS">
  <xsl:choose>
   <xsl:when test=
     "not(starts-with(name(), $vPrefix)
        and
          namespace-uri() = $pOldNamespace
         )">
     <xsl:element name="{name()}" namespace="{namespace-uri()}">
         <xsl:copy-of select=
           "namespace::*
                 [not(name() = $vPrefix
                    and
                      . = $pOldNamespace
                      )
                ]"/>
       <xsl:apply-templates select="@*"/>
       <xsl:apply-templates select="node()" mode="removeNS"/>
     </xsl:element>
   </xsl:when>
  </xsl:choose>
 </xsl:template>

 <xsl:template match="@mustUnderstand">
  <xsl:attribute name="{name()}">0</xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

当这一转变适用于XML文件时:

<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <soapenv:Header>
        <wsse:Security mustUnderstand="1">
            <wsse:UsernameToken>
                <wsse:Username>test</wsse:Username>
                <wsse:Password>test</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <hel:docTypeRef_tns_sayHello xmlns:hel="http://aaa/bbb.fr">
            <arg0>John</arg0>
            <arg1>111-222-333</arg1>
        </hel:docTypeRef_tns_sayHello>
    </soapenv:Body>
</soapenv:Envelope>

<t, 正确结果::

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
   <soapenv:Header>
      <wsse:Security mustUnderstand="0">
         <wsse:UsernameToken>
            <wsse:Username>test</wsse:Username>
            <wsse:Password>test</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <hel:docTypeRef_tns_sayHello xmlns:hel="http://test.fr">
         <arg0>John</arg0>
         <arg1>111-222-333</arg1>
      </hel:docTypeRef_tns_sayHello>
   </soapenv:Body>
</soapenv:Envelope>

xsl:名称指示可用于动态构建动态(法定身份不明)部件的新名称空间。

Here is a small example how with XSLT 1.0 to add a new, non-existent at the start of the transformation namespace node:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
 exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <xsl:variable name="vrtfDoc">
   <t xmlns:hel="http://test.fr"/>
  </xsl:variable>

  <xsl:variable name="vNS" select=
   "ext:node-set($vrtfDoc)/*/namespace::*
                               [name()= hel ]"/>

  <xsl:element name="{name()}"
               namespace="{namespace-uri()}">
    <xsl:copy-of select="namespace::*"/>

    <xsl:copy-of select="$vNS"/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

当这一转变适用于本十份LL文件时:

<t xmlns:someNS="some:NS"/>

它重新编号为<代码>t及其所有名称空间节点,并在其中添加一个新名称空间节点:

<t xmlns:someNS="some:NS" xmlns:hel="http://test.fr"/>

www.un.org/Depts/DGACM/index_spanish.htm II. 这里是一个完整的XSLT 2.0解决方案:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pElemName" select=" hel:docTypeRef_tns_sayHello "/>
 <xsl:param name="pOldNamespace" select=" http://aaa/bbb.fr "/>
 <xsl:param name="pNewNamespace" select=" http://test.fr "/>

 <xsl:variable name="vPrefix" select="substring-before($pElemName,  : )"/>

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

 <xsl:template match="/*">
  <xsl:element name="{name()}" namespace="{namespace-uri()}">
   <xsl:namespace name="{$vPrefix}" select="$pNewNamespace"/>

   <xsl:copy-of select=
       "namespace::*
             [not(name() = $vPrefix
                and
                  . = $pOldNamespace
                  )
              ]"/>

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

 <xsl:template match="*">
  <xsl:choose>
      <xsl:when test=
       "not(name() = $pElemName
          and
            namespace-uri() = $pOldNamespace
           )
       ">
        <xsl:call-template name="identity"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:element name="{name()}" namespace="{$pNewNamespace}">
         <xsl:copy-of select=
           "namespace::*
                 [not(name() = $vPrefix
                    and
                      . = $pOldNamespace
                      )
                ]"/>

         <xsl:apply-templates select="@*"/>

         <xsl:apply-templates select="node()" mode="removeNS"/>
        </xsl:element>
      </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

 <xsl:template match="*" mode="removeNS">
  <xsl:choose>
   <xsl:when test=
     "not(starts-with(name(), $vPrefix)
        and
          namespace-uri() = $pOldNamespace
         )">
     <xsl:element name="{name()}" namespace="{namespace-uri()}">
         <xsl:copy-of select=
           "namespace::*
                 [not(name() = $vPrefix
                    and
                      . = $pOldNamespace
                      )
                ]"/>
       <xsl:apply-templates select="@*"/>
       <xsl:apply-templates select="node()" mode="removeNS"/>
     </xsl:element>
   </xsl:when>
  </xsl:choose>
 </xsl:template>

 <xsl:template match="@mustUnderstand">
  <xsl:attribute name="{name()}">0</xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the same XML document (above), the wanted, correct result is produced:

<soapenv:Envelope xmlns:hel="http://test.fr"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
   <soapenv:Header>
      <wsse:Security mustUnderstand="0">
         <wsse:UsernameToken>
            <wsse:Username>test</wsse:Username>
            <wsse:Password>test</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <hel:docTypeRef_tns_sayHello>
         <arg0>John</arg0>
         <arg1>111-222-333</arg1>
      </hel:docTypeRef_tns_sayHello>
   </soapenv:Body>
</soapenv:Envelope>




相关问题
When test hanging in an infinite loop

I m tokenising a string with XSLT 1.0 and trying to prevent empty strings from being recognised as tokens. Here s the entire function, based on XSLT Cookbook: <xsl:template name="tokenize"> ...

quick xslt for-each question

Let s say I have an XML document that has this: <keywords> <keyword>test</keyword> <keyword>test2</keyword> <keyword>test3</keyword> <keyword>test4</...

XSLT Transform XML with Namespaces

I m trying to transform some XML into HTML using XSLT. Problem: I can t get it to work. Can someone tell me what I m doing wrong? XML: <ArrayOfBrokerage xmlns:i="http://www.w3.org/2001/...

XSLT output to HTML

In my XSLT file, I have the following: <input type="button" value= <xsl:value-of select="name">> It s an error as it violates XML rule. What I actually want is having a value from an ...

Mangling IDs and References to IDs in XML

I m trying to compose xml elements into each other, and the problem I am having is when there s the same IDs. Basically what I need to do is mangle all the IDs in an xml file, as well as the ...

Sharepoint 2007 Data view Webpart custom parameters

I m sort of new to the custom parameters that can be setup on a DataView Webpart. There are 6 options: - None - Control - Cookie - Form - QueryString - Server Variable I think that None, Cookie and ...

热门标签