简体   繁体   中英

Detect namespace of an existing node and insert a new node of the same namespace into an xml document via Xquery

I'm trying to dynamically create some new nodes in an xml document based on the nodes around it. The issue I am having is that I want to add a new node after stock that has the same namespace as stock. While it would be easy for this example, I want to be able to do it without knowing the namespaces around me. Is it possible to copy and then rename a node so that I can preserve its namespace and possibly other attributes?

ie if I had

<?xml version="1.0" encoding="UTF-8"?>
<nsX:bookstore xmlns:nsX="http://namespace1" xmlns:nsY="http://namespace2">
  <nsX:bookList>
    <nsX:book category="COOKING">
      <nsX:title lang="en">Everyday Italian</nsX:title>
      <nsY:stock>1</nsY:stock>
    </nsX:book>
    <nsX:book category="CHILDREN">
      <nsX:title lang="en">Harry Potter</nsX:title>
      <nsY:stock>0</nsY:stock>
    </nsX:book>
    <nsX:book category="WEB">
      <nsX:title lang="en">XQuery Kick Start</nsX:title>
      <nsY:stock>1</nsY:stock>
    </nsX:book>
    <nsX:book category="WEB">
      <nsX:title lang="en">Learning XML</nsX:title>
      <nsY:stock>0</nsY:stock>
    </nsX:book>
  </nsX:bookList>
</nsX:bookstore>

and wanted to generate the following without already knowing what namespaces were present.

<?xml version="1.0" encoding="UTF-8"?>
<nsX:bookstore xmlns:nsX="http://namespace1" xmlns:nsY="http://namespace2">
  <nsX:bookList>
    <nsX:book category="COOKING">
      <nsX:title lang="en">Everyday Italian</nsX:title>
      <nsY:stock>1</nsY:stock>
      <nsY:newNode></nsY:newNode>
    </nsX:book>
    <nsX:book category="CHILDREN">
      <nsX:title lang="en">Harry Potter</nsX:title>
      <nsY:stock>0</nsY:stock>
      <nsY:newNode></nsY:newNode>
    </nsX:book>
    <nsX:book category="WEB">
      <nsX:title lang="en">XQuery Kick Start</nsX:title>
      <nsY:stock>1</nsY:stock>
      <nsY:newNode></nsY:newNode>
    </nsX:book>
    <nsX:book category="WEB">
      <nsX:title lang="en">Learning XML</nsX:title>
      <nsY:stock>0</nsY:stock>
      <nsY:newNode></nsY:newNode>
    </nsX:book>
  </nsX:bookList>
</nsX:bookstore>

Currently I create the new node using xQuery with my BaseXDB

insert node <newNode></newNode> after $v/*:bookList/*:book/*:stock

(where $v is bookstore)

How do I detect the namespace of the stock node and then apply it to the new nodes I am making?

Use fn:namespace-uri() to get the namespace URI of a node, then, create a QName from a URI and a local-name with fn:QName() . Finally, create an element from a QName using the element constructor:

let $ns-uri := ($v/*:bookList/*:book/*:stock)[1]/fn:namespace-uri(.)
let $new-node := element { fn:QName($ns-uri, "newNode") } {}
return
  insert node $new-node after $v/*:bookList/*:book/*:stock

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM