Writing GraphML with XOM? - java

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)

Related

Access JDOM elements independent of its namespace

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.

How can I use XPath to resolve the following 'tags' values?

The xml file is :
<xml-fragment xmlns:xyz="http://someurl">
<xyz:xyzcontent>
<contentattribute>
<key>tags</key>
<value>tag1, tag2</value>
</contentattribute>
</xyz:xyzcontent>
...
I've tried the following:
XPathExpression createdDateExpression = xpath.compile("/contentattribute/key/attribute::tags/value");
There are several problems with your query.
The XML is broken (root tag not closed) -- probably just a copy/paste mistake
You're starting somewhere right in the middle of the XML tree, but actually try to query from the root node. Use the descendant-or-self-axis // in the beginning.
Which attribute are you querying using the attribute-axis? There is none.
Where did you register the namespaces? What namespace is xyz, anyway? I guess it's actually vp, but you obfuscated incompletely (or are not giving all relevant parts of the document).
Use predicates and string comparison to filter at axis steps.
Try following:
Make sure to register the namespace, have a look at the reference for that (or give more information).
Use the XPath query //contentattribute[key='tags']/value

Java xml creation with JDOM/XML

I have an problem in creating xml with the
<c:condition>
<a:condition>
<fieldName>fieldName</fieldName>
<fieldTest>fieldTest</fieldTest>
<fieldValues>
<fieldValue>fieldValue</fieldValue>
</fieldValues>
</a:condition>
<operator>operator</operator>
<a:condition>
<fieldName>fieldName</fieldName>
<fieldTest>fieldTest</fieldTest>
<fieldValues>
<fieldValue>fieldValue</fieldValue>
</fieldValues>
</a:condition>
</c:condition>
Above is the xml tag given to me.
I need to create this tag using the JDOM/XML in java.
So I am using
Element complexCondition = new Element("c:condition");
code to create "c:condition" tag.
But I am getting error
org.jdom.IllegalNameException: The name "c:condition" is not legal for JDOM/XML elements: Element names cannot contain colons.
So don't have any idea what is going wrong.
As I am new to the xml's and JDOM.
Please help me out with this issue.
c:
is a namespace prefix. you should create your element with namespace. check the constructor :
Element(java.lang.String name, java.lang.String prefix, java.lang.String uri)
Creates a new element with the supplied (local) name and a namespace given by the supplied prefix and URI combination.

Reading XML data between tags

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

Using XPath in XMLObject to query by namespace

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.

Categories