1

我有一个 SOAP 请求,我正在尝试使用 XSLT 进行转换。我想为请求中的每个元素添加命名空间限定符。我需要使用两个不同的命名空间。这是我要转换的 XML:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" >
   <soapenv:Header/>
   <soapenv:Body>
      <PingRq>
         <RqUID>1</RqUID>
         <RequestContext>
              <ClientUserID>1</ClientUserID>
              <ClientName>Big Company</ClientName>
              <ClientApplication>
                  <AppName>TestApp</AppName>
                  <AppVersion>1</AppVersion>
              </ClientApplication>
              <ClientLangPref>En-US</ClientLangPref>
              <ClientDt>Mar-29-2013</ClientDt>
         </RequestContext>
      </PingRq>
      </soapenv:Body>
    </soapenv:Envelope

这是我想将其转换为:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" >
      <soapenv:Header/>
      <soapenv:Body>
       <PingRq namespace="http://www.ns1.com">
         <RqUID namespace="http://www.ns2.com">1</RqUID>
         <RequestContext namespace="http://www.ns2.com">
              <ClientUserID namespace="http://www.ns2.com">1</ClientUserID>
              <ClientName namespace="http://www.ns2.com">Big Company</ClientName>
              <ClientApplication namespace="http://www.ns2.com">
                  <AppName namespace="http://www.ns2.com">TestApp</AppName>
                  <AppVersion namespace="http://www.ns2.com">1</AppVersion>
              </ClientApplication>
              <ClientLangPref namespace="http://www.ns2.com">En-US</ClientLangPref>
              <ClientDt namespace="http://www.ns2.com">Mar-29-2013</ClientDt>
         </RequestContext>
         </PingRq>
       </soapenv:Body>
    </soapenv:Envelope>

这是我的样式表

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" 
     xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

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

     <xsl:template match="PingRq">
    <xsl:element name="{local-name()}" namespace="http://www.ns1.com">
        <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
     </xsl:template>
     <xsl:template match="PingRq/*">
    <xsl:element name="{local-name()}" namespace="http://www.ns2.com">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
     </xsl:template>        
    </xsl:stylesheet>

这是我得到的结果。

<?xml version="1.0" encoding="UTF-8"?>
     <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
       <soapenv:Header/>
       <soapenv:Body>
        <PingRq xmlns="http://www.ns1.com">
         <RqUID xmlns="http://www.ns2.com">1</RqUID>
         <RequestContext xmlns="http://www.ns2.com">
              <ClientUserID xmlns="">1</ClientUserID>
              <ClientName xmlns="">Big Company</ClientName>
              <ClientApplication xmlns="">
                  <AppName>TestApp</AppName>
                  <AppVersion>1</AppVersion>
              </ClientApplication>
              <ClientLangPref xmlns="">En-US</ClientLangPref>
              <ClientDt xmlns="">Mar-29-2013</ClientDt>
         </RequestContext>
        </PingRq>
       </soapenv:Body>
      </soapenv:Envelope>

我不知道为什么我在后代中得到空的命名空间属性。有人有什么想法吗???

4

1 回答 1

1

PingRq/*xpath 只匹配元素的直接子元素PingRq。要将其所有后代元素放在某个命名空间中,您可以这样做:

<xsl:template match="PingRq//*">
  <xsl:element name="{local-name()}" namespace="http://www.ns2.com">
    <xsl:apply-templates select="@*|node()"/>
   </xsl:element>
</xsl:template>

请注意,结果并未显示所有后代的命名空间声明:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
  <soapenv:Header />
  <soapenv:Body>
    <PingRq xmlns="http://www.ns1.com">
      <RqUID xmlns="http://www.ns2.com">1</RqUID>
      <RequestContext xmlns="http://www.ns2.com">
        <ClientUserID>1</ClientUserID>
        <ClientName>Big Company</ClientName>
        <ClientApplication>
          <AppName>TestApp</AppName>
          <AppVersion>1</AppVersion>
        </ClientApplication>
        <ClientLangPref>En-US</ClientLangPref>
        <ClientDt>Mar-29-2013</ClientDt>
      </RequestContext>
    </PingRq>
  </soapenv:Body>
</soapenv:Envelope>

但这是意料之中的,因为下面的元素RequestContext从它们的父级继承了它们的命名空间。

于 2013-02-05T03:44:07.903 回答