Ahmed El Saeed
Ahmed El Saeed

Reputation: 31

How to fix an addition namespace attribute after executes a query?

i have the following xml file.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:ns="http://example.com/ns">
  <soapenv:Header xmlns:ns1="http://www.ns1.com"/>
   <soapenv:Body>
     <ns:request>
      <ns:customer>
       <ns:id>123</ns:id>
       <ns:name type="NCHZ">John Brown</ns:name>
      </ns:customer>
     </ns:request>
   </soapenv:Body>
</soapenv:Envelope>

when i get <ns:request> element using the following xquery/xpath.

declare namespace soapenv="http://schemas.xmlsoap.org/soap/envelope/"; declare namespace ns="http://example.com/ns"; //soapenv:Envelope/soapenv:Body/ns:request

the result will be

<ns:request xmlns:ns="http://example.com/ns" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <ns:customer>
        <ns:id>123</ns:id>
        <ns:name type="NCHZ">John Brown</ns:name>
    </ns:customer>
</ns:request>

why xmlns:ns="http://example.com/ns" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" attribute in the <ns:request> element is added although it doesn't exist on the main xml file ? and how to fix it?

Upvotes: 0

Views: 157

Answers (2)

Martin Honnen
Martin Honnen

Reputation: 167611

You can get rid of the in-scope but unused namespace xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" by using declare copy-namespaces no-preserve and a document constructor in XQuery e.g.

declare copy-namespaces no-preserve, no-inherit;

declare namespace soapenv="http://schemas.xmlsoap.org/soap/envelope/"; 
declare namespace ns="http://example.com/ns"; 

document {
//soapenv:Envelope/soapenv:Body/ns:request
}

https://xqueryfiddle.liberty-development.net/gWcDMes

so that way the result would be

<ns:request xmlns:ns="http://example.com/ns">
  <ns:customer>
   <ns:id>123</ns:id>
   <ns:name type="NCHZ">John Brown</ns:name>
  </ns:customer>
 </ns:request>

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163370

You need to understand the way namespaces work in the XDM data model. Every element node has a set of in-scope namespaces (prefix-uri) bindings, which are obtained by looking at all the namespace declarations in ancestor elements. When an element node is serialized, all the in-scope namespaces are serialized as namespace declaration attributes, because the processor doesn't know which of them are needed and which aren't.

In your case one of the namespaces (ns) is needed (because it's used in element names) while the other one isn't (it isn't used anywhere).

In XSLT (2.0+) you can get rid of unused namespaces using <xsl:copy> with copy-namespaces='no'. But XPath always gives you the input nodes unchanged: so if an element has two in-scope namespaces in the input, it will still have two in-scope namespaces in the output, and these will be visible when the element is serialized.

Upvotes: 1

Related Questions