Cannot find JDOM node through xpath after clone - java

I have a xml document, and I use JDOM to parse it and use XPATH API provided by JDOM to find some element, it works well.
Example:
<person>
<info name="gg" age="0" hobby="hi" />
</person>
Through API:
XPath.selectSingleNode(baseElement,"//*[local-name()='info");
I can get the correct info.
Then I try to clone a new baseElement with baseElement.clone().
After that, if I try:
XPath.selectSingleNode(baseElementClone,"//*[local-name()='info");
I got nothing.
The only diff I can image is that after clone, it will lose the parent info. But I dont why it will affect the search result.
Pls let me know if you think the question is unclear.
BTW, my JDOM version is 1.0
Br,
Tim

Related

xml parsing using sax

I want to parse XML file using SaxParser. I'm trying to fetch the data associated to a tag or its attributes. The XML is in the following format.
<con>
<fig>
<abc>
<name xyz="">
<id>2</id>
</name>
</abc>
</fig>
</con>
I tried with couple of example but not succeeded in the fetching the data, I am requesting you to provide me any suggestion or and working example to increase my knowledge on parsing using SAX.
Use a DOM parser as your xml is very small and its easy to get what you are asking for.
There are my example and help available online, Please Google your question before posting on the stack over flow from next time.
Please check the following links which has good example for saxParsing
How to read XML file in Java – (SAX Parser)
Getting Attributes And its Value
hope this help you.

XML Parent & child Attributes reading in java?

I have the following data in my XML file.
<main>
<Team Name="Development" ID="10">
<Emp Source="Business" Total="130" Active="123" New="12" />
<Emp Source="Business" Total="131" Active="124" New="13" />
</Team>
<Team Name="Testing" ID="10">
<Emp Source="Business" Total="133" Active="125" New="14" />
</Team>
</main>
I want to read above data & store values into arrays,Can any one help on these?
Not sure why you need to convert those xml into Arrays, anyhow you can read xml and parse it by several ways. Normally we use DOM or Stax Parser and a Tutorial link is here, also here is a Java SAX Parsing Example tutorial.
Hope this can help you to achieve your goal. Update your question again if you stuck anywhere.
You can use parser in JAVA to parse the XML document. The package in java for this purpose is javax.xml.parsers . DocumentBuilder parses XML into a Document and Document is a tree structured data structure that is DOM(Document Object Model) readable file. Its nodes can be traversed/ changed/ accessed by DOM methods.
Here is a very good tutorial on XML DOM: http://www.roseindia.net/xml/dom/
and more specifically: http://www.roseindia.net/xml/dom/accessing-xml-file-java.shtml
also you can always refer to w3school for more theory on DOM!

how to use text() in jxpath

Can you get the text() of a jxpath element or does it not work?
given some nice xml:
<?xml version="1.0" encoding="UTF-8"?>
<AXISWeb xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="AXISWeb.xsd">
<Action>
<Transaction>PingPOS</Transaction>
<PingPOS>
<PingStep>To POS</PingStep>
<PingDate>2012-11-15</PingDate>
<PingTime>16:35:57</PingTime>
</PingPOS>
<PingPOS>
<PingStep>POS.PROCESSOR18</PingStep>
<PingDate>2012-11-15</PingDate>
<PingTime>16:35:57</PingTime>
</PingPOS>
<PingPOS>
<PingStep>From POS</PingStep>
<PingDate>2012-11-15</PingDate>
<PingTime>16:35:57</PingTime>
</PingPOS>
</Action>
</AXISWeb>
//Does not work:
jxpc.getValue("/AXISWeb/Action/PingPOS[1]/PingStep/text()");
//Does not work:
jxpc.getValue("/action/pingPOS[1]/PingStep/text()");
//Does not work:
jxpc.getValue("/action/pingPOS[1]/PingStep[text()]");
I know I can get the text from using
jxpc.getValue("/action/pingPOS[1]/PingStep");
But that's not the point.
Shouldn't text() work? I could find no examples....
P.S. It's also very very picky about case and capitalization. Can you turn that off somehow?
Thanks,
-G
/AXISWeb/Action/PingPOS[1]/PingStep/text() is valid XPath for your document
But, from what I can see from the user guide of jxpath (note: I don't know jxpath at all), getValue() is already supposed to return the textual content of a node, so you don't need to use the XPath text() at all.
So you may use the following:
jxpc.getValue("/AXISWeb/Action/PingPOS[1]/PingStep");
Extracted from the user guide:
Consider the following XML document:
<?xml version="1.0" ?>
<address>
<street>Orchard Road</street>
</address>
With the same XPath, getValue("/address/street"), will return the string "Orchard Road", while
selectSingleNode("/address/street") - an object of type Element (DOM
or JDOM, depending on the type of parser used). The returned Element
is, of course, <street>Orchard Road</street>.
Now about case insensitive query on tag names, if you are using XPath 2 you can use lower-case() and node() but this is not really recommended, you may better use correct names.
/*[lower-case(node())='axisweb']/*[lower-case(node())='action']/...
or if using XPath 1, you may use translate() but it gets even worse:
/*[translate(node(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz') = 'axisweb']/*[translate(node(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz') = 'action']/...
All in all, try to ensure that you use correct query, you know it is case sensitive, so it's better to pay attention to it. As you would do in Java, foo and fOo are not the same variables.
Edit:
As I said, XML and thus XPath is case sensitive, so pingStep cannot match PingStep, use the correct name to find it.
Concerning text(), it is part of XPath 1.0, there is no need for XPath 2 to use it. The JXPath getValue() is already doing the call to text() for you. If you want to do it yourself you will have to use selectSingleNode("//whatever/text()") that will returns an Object of type TextElement (depending on the underlying parser).
So to sum up, the method JXPathContext.getValue() already does the work to select the node's text content for you, so you don't need to do it yourself and explicitly call XPath's text().
From a post that I've anserwed before the method .getTextContent() do the job for you.
No need to use "text()" when you evaluate the Xpath.
Example :
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("D:\\Loic_Workspace\\Test2\\res\\test.xml"));
System.out.println(doc.getElementsByTagName("retCode").item(0).getTextContent());
If not, you will get the tag and the value. If you want do more take a look at this

How can I do type-safe Xpath queries in Java?

I'm currently using JDOM for doing some simple XML parsing, and it seems like nothing's type safe - I had a similar issue with using the built-in Java DOM parser, just with lots more API to wade through.
For example, XPath.selectNodes takes an Object as its argument and returns a raw list, which just feels a little Java 1.1
Are there generic-ized XML and XPath libraries for Java, or is there some reason why it's just not possible to do XPath queries in a type-safe way?
If you're familiar with CSS selectors on HTML, it may be good to know that Jsoup supports XML as well.
Update: OK, that was given the downvote apparently a very controversial answer. It may however end up to be easier and less verbose than Xpath when all you want is to select node values. The Jsoup API is namely very slick. Let's give a bit more concrete example. Assuming that you have a XML file which look like this:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="1">
<name>John Doe</name>
<age>30</age>
<address>
<street>Main street 1</street>
<city>Los Angeles</city>
</address>
</person>
<person id="2">
<name>Jane Doe</name>
<age>40</age>
<address>
<street>Park Avenue 1</street>
<city>New York</city>
</address>
</person>
</persons>
Then you can traverse it like follows:
Document document = Jsoup.parse(new File("/persons.xml"), "UTF-8");
Element person2 = document.select("person[id=2]").first();
System.out.println(person2.select("name").text());
Elements streets = document.select("street");
for (Element street : streets) {
System.out.println(street.text());
}
which outputs
Jane Doe
Main street 1
Park Avenue 1
Update 2: since Jsoup 1.6.2 which was released March 2012, XML parsing is officially supported by the Jsoup API.
AFAIK all of the xml queries in java are non-typesafe and most are java 1.3 compatible. That said my favorite parser/generator is the xml pull parser (xmlpp) style parser. I believe java has XmlStreamReader and XmlStreamWriter if you're using 1.6 which are almost the same as the xmlpp library. I especially like that I can write a method getFoo that takes a stream reader and pulls from it and returns a Foo object. It's sort of the best between DOM and SAX. I think it may be referred to as StAX by some.
I'm getting a little ramble-y so I'm quitting now

The markup must be well-formed

First off, let me say I am a new to SAX and Java.
I am trying to read information from an XML file that is not well formed.
When I try to use the SAX or DOM Parser I get the following error in response:
The markup in the document following the root element must be well-formed.
This is how I set up my XML file:
<format type="filename" t="13241">0;W650;004;AG-Erzgeb</format>
<format type="driver" t="123412">001;023</format>
...
Can I force the SAX or DOM to parse XML files even if they are not well formed XML?
Thank you for your help. Much appreciated.
Haythem
Your best bet is to make the XML well-formed, probably by pre-processing it a bit. In this case, you can achieve that simply by putting an XML declaration on (and even that's optional) and providing a root element (which is not optional), like this:
<?xml version="1.0"?>
<wrapper>
<format type="filename" t="13241">0;W650;004;AG-Erzgeb</format>
<format type="driver" t="123412">001;023</format>
</wrapper>
There I've arbitrarily picked the name "wrapper" for the root element; it can be whatever you like.
Hint: using sax or stax you can successfully parse a not well formed xml document until the FIRST "well formed-ness" error is encountered.
(I know that this is not of too much help...)
As the DOM will scan you xml file then build a tree, the root node of the tree is like the as 1 Answer. However, if the Parser can't find the or even , it can even build the tree. So, its better to do some pre-processing the xml file before parser it by DOM or Sax.

Categories

Resources