0

I have an xquery file that transforms from a.xml to b.xml. Below is an example of my x-query:

<TestMessage>
    <Header>
      <MessageType>
           {for $x in doc("input.xml")//Test/NewHeader return 
        if ($x/MessageType/text() = "FIRST") then "FirstMessageType"
        else "SecondMessageType"
    }   
      </MessageType>
    </Header>
 </TestMessage>

This works fine and populates my MessageType properly. But I need to add a namespace as an attribute to the TestMessage element. So, when I do,

<TestMessage xmlns="http://www.testsource.com/TestMessage">
    <Header>
      <MessageType>
           {for $x in doc("input.xml")//Test/NewHeader return 
        if ($x/MessageType/text() = "FIRST") then "FirstMessageType"
        else "SecondMessageType"
    }   
      </MessageType>
    </Header>
 </TestMessage>

The xquery result has an empty MessageType element. I haven't changed anything except add the namespace in the x-query document. But I don't understand why this gives me a wrong resultant xml.

Any help would be greatly appreciated.

thanks a lot!

1 Answer 1

2

When you add a default namespace to the TestMessage element, that namespace is also applied to the XPath you are executing underneath it: doc("input.xml")//Test/NewHeader and ($x/MessageType/text().

If that content doesn't have a namespace, then the easiest thing to do would be to declare a namespace prefix in the XML root: xmlns:test="http://www.testsource.com/TestMessage, and prefix all of the elements: <test:TestMessage xmlns:test="http://www.testsource.com/TestMessage>, <test:Header> and so on.

One way to get around this is to execute the no-namespace XQuery code outside of the default-namespaced XML:

declare function local:get-message-type()
{
  for $x in doc("input.xml")//Test/NewHeader 
  return 
    if ($x/MessageType/text() = "FIRST") 
    then "FirstMessageType"
    else "SecondMessageType"
};

<TestMessage xmlns="http://www.testsource.com/TestMessage">
    <Header>
      <MessageType>
           { local:get-message-type() }   
      </MessageType>
    </Header>
</TestMessage>
Sign up to request clarification or add additional context in comments.

4 Comments

But the root element of my resultant xml should look exactly like this: <TestMessage xmlns="testsource.com/TestMessage">
Other than the presentation, there's no difference in the resultant XML using a default namespace or a namespace prefix. Any application will treat them the same. However, see the updated solution for an alternative.
@wst is correct. This is called "namespace inheritance" in XQuery. For more on this, see docs.marklogic.com/guide/xquery/namespaces#id_49014.
Wow I was struggling to figure out why I kept getting an empty response from my xpath inside of the xml that had a declared namespace like you do there with xmlns. Using a function outside that namespace to get the info and plug it in thereby inheriting the specified namespace did the trick! I couldn't figure out a cleaner way and I really appreciate this answer!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.