I was trying to propagate the following xml message to the File Output Node in IBM Integration Bus.
<Resto xmlns = 'https://stackoverflow.com'><Location network_id="5dfweg68h"><Category>Continental</Category></Location></Resto>
Following was my associated Java code to construct the above xml message:
MbElement xmlBody = outMessage.getRootElement().createElementAsLastChild(MbXMLNSC.PARSER_NAME);
MbElement xmlParent = xmlBody.createElementAsLastChild(MbElement.TYPE_NAME, "Resto", null);
xmlParent.createElementAsLastChild(MbXMLNSC.ATTRIBUTE, "xmlns", "https://stackoverflow.com");
MbElement locationParser = xmlParent.createElementAsLastChild(MbElement.TYPE_NAME, "Location", null);
locationParser.createElementAsLastChild(MbXMLNSC.ATTRIBUTE, "network_id", "5dfweg68h");
locationParser.createElementAsLastChild(MbElement.TYPE_NAME_VALUE,"Category","Continental");
On debugging my application, I got XML write errors. I pondered a bit for the necessary solution, and found that adding namespace prefix would solve the problem. Can't it be done without the addition of a prefix? If no, can anyone guide me, in assigning the necessary value by suggesting the necessary changes to be done in Java compute node?
Note: The string assigned to xmlns should be within single quotes in the xml message.
Use constant MbXMLNSC.NAMESPACE_DECLARATION to declare the namespace:
MbElement xmlBody = outMessage.getRootElement().createElementAsLastChild(MbXMLNSC.PARSER_NAME);
MbElement xmlParent = xmlBody.createElementAsLastChild(MbElement.TYPE_NAME, "Resto", null);
xmlParent.createElementAsFirstChild(MbXMLNSC.NAMESPACE_DECLARATION, "xmlns", "https://stackoverflow.com");
If your XSD defines that the XML elements are qualified, you have to set the namespace explicitly. Examples:
xmlParent.setNamespace("https://stackoverflow.com");
locationParser.setNamespace("https://stackoverflow.com");
locationParser.createElementAsLastChild(MbElement.TYPE_NAME_VALUE,
"Category", "Continental").setNamespace("https://stackoverflow.com");
Related
I have a xml like below:
<v2:Root xmlns:v2="www.example.com/xsd/">
<ABC>test data</ABC>
<ABC>test data1</ABC>
<ABC>test data2</ABC>
</v2:Root>
When I'm accessing ABC element using JDOM2, i'm getting the element value in debug like
[Element:ABC[Namespace:"www.example.com/xsd/"]].
That's why i couldn't access the element by just using Xpath expression "//ABC". I'm forced to use expression "/*[local-name()='ABC']".Then it works.
Now, my requirement is to acces the elemnt using expression "//ABC" only. Is there any way?
Thanks in advance for any help.
I think you are mistaken about what your XML actually looks like. I believe you also must have:
xmlns="www.example.com/xsd/"
in there somewhere otherwise your ABC Elements would be in the NO_NAMESPACE namespace (and the ABC toString() method would look like: [Element:ABC] )
So, your XML snippet does not match the ABC Element toString() output.
If you fix your question it will be easier to suggest what your XPath expression should look like.
EDIT, assuming I am right that you have the additional redefinition of the default Namespace, then you can use the following JDOM to get the ABC elements:
XPathFactory xpf = XPathFactory.instance();
Namespace defns = Namespace.getNamespace("defns", "www.example.com/xsd/");
XPathExpression<Element> xpe = xpf.compile("//defns:ABC", Filters.element(), null, defns);
List<Element> abcs = xpe.evaluate(doc);
You should read the following exerpt from the XPath specification carefully:
A QName in the node test is expanded into an expanded-name using the namespace declarations from the expression context. This is the same way expansion is done for element type names in start and end-tags except that the default namespace declared with xmlns is not used: if the QName does not have a prefix, then the namespace URI is null (this is the same way attribute names are expanded). It is an error if the QName has a prefix for which there is no namespace declaration in the expression context.
final SAXBuilder builder = new SAXBuilder();
final Document xml = builder.build( file );
final Element root = (Element) xml.getRootElement();
Element child = root.getChild("Header", Namespace.getNamespace("http://www.editeur.org/icedis/claims"));
final XPathContext ctx = XPathContext.create(root);
This is the code I have. XPathContext is just wrapper around JXPathContext. As you see, 'child' variable using construction with Namespace and it won't work if I remove it.
But now I'm trying to get value from XML with XPath like this
ctx.getValue("/Header/SentDateTime")
And, ofcourse it always return null. It seems that solution is simple, but I can't find it in the internet. If I delete xmlns from XML file, everything will work, but this isn't an option. So how should I work with this xml?
Also, short version of XML file:
<?xml version="1.0" encoding="UTF-8"?>
<ICEDISClaimMessage version="0.1" xmlns="http://www.editeur.org/icedis/claims">
<Header>
<Sender>
<SenderIdentifier>
<SenderIDType>06</SenderIDType>
<IDValue>1234567890128</IDValue>
</SenderIdentifier>
<SenderName>Apogee Agency</SenderName>
</Sender>
<Addressee>
<AddresseeIdentifier>
<AddresseeIDType>06</AddresseeIDType>
<IDValue>2345678901237</IDValue>
</AddresseeIdentifier>
</Addressee>
<MessageNumber>111</MessageNumber>
<SentDateTime>20101001</SentDateTime>
<MessageNote>Sample file 1: a claim made by an agent to a publisher for a journal issue not yet delivered</MessageNote>
</Header>
</<ICEDISClaimMessage>
You need to use an XPath expression with a namespace context. It would have to look something like this:
final XPathContext ctx = XPathContext.create(root);
ctx.addNamespaceMapping("ns", "http://www.editeur.org/icedis/claims");
... = ctx.getValue("/ns:Header/ns:SentDateTime");
NB: I don't know whether JXPath supports namespaces, and if it does, how it is set up.
And, by the way, it looks like you are using JDOM (SAXBuilder). In that case I would recommend using the JDOM built in XPath functions instead of building a wrapper.
I have a XML for which i am writing a servlet to pick up contents from the XML. One such tag is <itunes:author>Jonathan Kendrick</itunes:author>
I need to get author value for this. because of :
I tried using namespace and using escape sequence for : but it did not worked for me.
For rest of other XML elements i am simply using
String link=node.getChildText("link").toString();
I am using Jdom parser
in your XML the sequernce 'itunes:author' represents what's called a Q-Namem a "Qualified Name". In XML it consists of a 'Namespace prefix', and a 'Local Name'. In your example, the namespace prefix is 'itunes', and the 'local name' is 'author'.
What you want is the 'author' element in the namespace linked to the prefix 'itunes'. The actual namespace is normally a full URL. I believe the full URL for your example is probably xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd", but you should check that.
So, the Namespace is "http://www.itunes.com/dtds/podcast-1.0.dtd", it's prefix is declared to be 'itunes' (but it could be something else - the actual prefix name is not technically important...)
You want to get the 'author' in the 'http://www.itunes.com/dtds/podcast-1.0.dtd' Namespace so you want:
String author = node.getChildText("author", Namespace.getNamespace("http://www.itunes.com/dtds/podcast-1.0.dtd"));
For more information on Namespaces check out: http://www.w3schools.com/xml/xml_namespaces.asp
I have a simple XML document
<abc:MyForm xmlns:abc='http://myform.com'>
<abc:Forms>
<def:Form1 xmlns:def='http://decform.com'>
....
</def:Form1>
<ghi:Form2 xmlns:ghi='http://ghiform.com'>
....
</ghi:Form2>
</abc:Forms>
</abc:MyForm>
I'm using XMLObjects from Apache and when I try to do the following xpath expression it works perfectly
object.selectPath("declare namespace abc='http://myform.com'
abc:Form/abc:Forms/*");
this gives me the 2 Form nodes (def and ghi). However I want to be able to query by specifying a namespace, so let's say I only want Form2. I've tried this and it fails
object.selectPath("declare namespace abc='http://myform.com'
abc:Form/abc:Forms/*
[namespace-uri() = 'http://ghiform.com']");
The selectPath returns 0 nodes. Does anyone know what is going on?
Update:
If I do the following in 2 steps, then I can get the result that I want.
XmlObject forms = object.selectPath("declare namespace abc='http://myform.com'
abc:Form/abc:Forms")[0];
forms.selectPath("*[namespace-uri() = 'http://ghiform.com']");
this gives me the ghi:Form node just like it should, I don't understand why it doesn't do it as a single XPath expression though.
Thanks
The simple answer is that you can't. The namespace prefix is just a shorthand for the namespace URI, which is all that matters.
For a namespace-aware parser, your two tags are identical.
If you really want to differentiate using the prefix (although you really, really shouldn't be doing it), you can use a non namespace-aware parser and just treat the prefix as if it was part of the element name.
But ideally you should read a tutorial on how namespaces work and try to use them as they were designed to be used.
I'm trying to write out a graphML document with XOM in java, but I can't figure out how to get all of the namespace declarations correct. To have valid graphML, I need to have a root element that looks like the following:
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
I've been able to get most of this by doing
Element root = new Element("graphml");
root.setNamespaceURI("http://graphml.graphdrawing.org/xmlns");
root.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
The problem is the last element of this tag, the xsi:schemaLocation. I can't figure out how to express this in XOM. I can't do it as a normal attribute, as that throws an exception(Attribute prefixes must be declared.) and doing it as an additional namespace declaration also results in an exception(NCNames cannot contain colons). Any ideas?
This should do it. Basically you didn't provide the namespace URI for xsi:schemaLocation attribute. Thus trying to create a prefixed attribute with no namespace which clearly won't work.
root.addAttribute(new Attribute("xsi:schemaLocation",
"http://www.w3.org/2001/XMLSchema-instance",
"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"));
Check here for the correct Attribute constructor
Attribute(String name, String URI, String value)