Как исправить дополнительный атрибут пространства имен после выполнения запроса? - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть следующий XML-файл.

<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>

, когда я получаю <ns:request> элемент, используя следующий xquery / xpath .

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

результатбудет

<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>

, почему атрибут xmlns:ns="http://example.com/ns" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" в элементе <ns:request> добавлен, хотя его нет в основном XML-файле?и как это исправить?

Ответы [ 2 ]

1 голос
/ 25 апреля 2019

Вы можете избавиться от встроенного, но неиспользуемого пространства имен xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/", используя declare copy-namespaces no-preserve и конструктор документа в XQuery, например

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

, поэтому результат будет

<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>
1 голос
/ 25 апреля 2019

Вам необходимо понять, как пространства имен работают в модели данных XDM. Каждый узел элемента имеет набор привязок пространств имен (prefix-uri) в области видимости, которые получаются при просмотре всех объявлений пространства имен в элементах-предках. Когда узел элемента сериализуется, все внутренние пространства имен сериализуются как атрибуты объявления пространства имен, потому что процессор не знает, какие из них необходимы, а какие нет.

В вашем случае требуется одно из пространств имен (ns) (поскольку оно используется в именах элементов), а другое - нет (оно нигде не используется).

В XSLT (2.0+) вы можете избавиться от неиспользуемых пространств имен, используя <xsl:copy> с copy-namespaces='no'. Но XPath всегда дает вам входные узлы без изменений: поэтому, если элемент имеет два пространства имен в области ввода, он все равно будет иметь два пространства имен в области вывода, и они будут видны при сериализации элемента.

...