SimpleXML, convert children with dynamic names to list - java

I'm using SimpleXML
http://simple.sourceforge.net/home.php
inside my Android app,
Im getting back data from API like this :
<Items>
<data_0>
<name> x1 </name>
<phone> y1 </phone>
</data_0>
<data_1>
<name> x2 </name>
<phone> y2 </phone>
</data_1>
<data_2> ... </data_2>
...
<data_n> ... </data_n>
</Items>
How I can write POJO class with simpleXML so that it accepts infinite number of <data_n> elements?

That is a horribly designed XML document and if you have any influence over the format you're receiving I'd suggest requesting a change to:
<Items>
<data id="0">
<name> x1 </name>
<phone> y1 </phone>
</data>
<data id="1">
<name> x2 </name>
<phone> y2 </phone>
</data>
<data id="2"> ... </data>
...
<data id="n"> ... </data>
</Items>
Personally I wouldn't even try to design the POJO for this and instead just clean up the XML (even simply by using string pattern replacement in it's string representation) to the format above (you can even get rid of the id attribute completely as place on the list will reflect it anyway), which subsequently can be defined as a List of data objects.
Unless you can guarantee a certain maximum number of data elements (then copy&paste for dozens of horribly named elements can do the trick), I don't think you can even design a POJO for this, since you can't also define the XML Schema for this document.

Related

JAXB unmarshall XML to Hashmap containing another Hashmap

I have the following XML which I want to unmarshall using JAXB:
<?xml version="1.0" encoding="UTF-8"?>
<questions>
<question id="1">
<text>What is the capital of Germany?</text>
<correctAnswer>2</correctAnswer>
<answers>
<answer id="1">
<text>Munich</text>
</answer>
<answer id="2">
<text>Berlin</text>
</answer>
</answers>
</question>
<question id="2">
<text>What is the capital of France?</text>
<correctAnswer>1</correctAnswer>
<answers>
<answer id="1">
<text>Paris</text>
</answer>
<answer id="2">
<text>Marseille</text>
</answer>
</answers>
</question>
</questions>
I want to create a HashMap:
HashMap<String, Question>
from which I can get the questions by their ID.
Each question object should also have a Hashmap:
HashMap<String, Answer>
from which I can get the answers by their ID.
I started off using the code from this thread: JAXB unmarshal XML elements to HashMap
Now I have two problems / questions:
The accepted answer in that thread suggests using "#XmlPath(".")", but for that I'm supposed to import an eclipse plugin:
import org.eclipse.persistence.oxm.annotations.XmlPath;
But I'm using IntelliJ, and I don't know which alternative import to use to get this working.
Even if I get the proposed solution "#XmlPath(".")" working, I still don't know how to implement the HashMap property within the question object (containing the answers).

Reserved Word Error XML

I have this SOAP Request that simply checks the balance of an account.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="urn:someurn">
<SOAP-ENV:Body>
<Execute xmlns="">
<sessionId xmlns="">SomeSessionID</sessionId>
<username xmlns="">SomeUserName</username>
<password xmlns="">SomePassword</password>
<command xmlns="">CommandName</command>
<data xmlns=""><?xml version="1.0"?><meta><accountNo></accountNo></meta>
</data>
</Execute>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Whenever I make the request this error occurs, I have read some stack questions regarding this that I need to clear that whitespaces I've already done that, I've also tried using html entities for the question marks still no avail.
The error is :XML error parsing SOAP payload on line 14: Reserved XML Name which is the data tag.
Anyone can help me here? Also, I'm using Java to make the Requests to the the server.
Line 14 is
<data xmlns=""><?xml version="1.0"?><meta><accountNo></accountNo></meta>
You cannot have an xml header (the <?xml...?> tag) anywhere in the XML except as the first line. You must encode everything inside the <data>...</data> using entities, as in:
<data xmlns=""><?xml version="1.0"?><meta> ...

Best way to create huge xml file by duplicating the element(including children) with dom or sax using Java

I have a xml file(ABC.xml) and i need to duplicate only the
<Transaction>...</Transaction>
multiple times(more than 100000 times) keeping the Header and Trailer intact creating NEW.xml whose final size may go upto 1GB. Also i have to increment the Uniqueid for every transaction in sequence.
As i m new to xml, i have been searching to this the best possible way, and im confused.
Can anyone please help me with the best way to do it(using DOM or SAX) and some piece of code.
Also can you please give me some links about it.
ABC.xml
========
<?xml version="1.0" encoding="UTF-8"?>
<Header><Datetime><date>20130209</date><Time>01:12</Time></Datetime></Header>
<Transaction>
<Uniqueid>1230001</Uniqueid>
<Affiliate>
<Name>abc</Name>
<Address>
<line1>aaaa</line1>
<line2>bbbb</line2>
<line3>cccc</line3>
</Address>
<Amount>123.00</Amount>
<Currency>USD</Currency>
<Purpose>
<line1>aaaa</line1>
<line2>bbbb</line2>
<line3>cccc</line3>
</Purpose>
</Affiliate>
</Transaction>
<Trailer><TotalTransactions>1</TotalTransactions><TotalAmount>123<TotalAmount> </Trailer>
NEW.xml
=======
<?xml version="1.0" encoding="UTF-8"?>
<Header><Datetime><date>20130209</date><Time>01:12</Time></Datetime></Header>
<Transaction>
<Uniqueid>1230001</Uniqueid>
<Affiliate>
<Name>abc</Name>
<Address>
<line1>aaaa</line1>
<line2>bbbb</line2>
<line3>cccc</line3>
</Address>
<Amount>123.00</Amount>
<Currency>USD</Currency>
<Purpose>
<line1>aaaa</line1>
<line2>bbbb</line2>
<line3>cccc</line3>
</Purpose>
</Affiliate>
</Transaction>
<Transaction>
<Uniqueid>1230002</Uniqueid>
<Affiliate>
<Name>abc</Name>
<Address>
<line1>aaaa</line1>
<line2>bbbb</line2>
<line3>cccc</line3>
</Address>
<Amount>123.00</Amount>
<Currency>USD</Currency>
<Purpose>
<line1>aaaa</line1>
<line2>bbbb</line2>
<line3>cccc</line3>
</Purpose>
</Affiliate>
</Transaction>
<Trailer><TotalTransactions>2</TotalTransactions><TotalAmount>246<TotalAmount></Trailer>
It would help if your source XML were well-formed - it needs an outer wrapper element.
There are a number of XQuery processors available in Java, for example Saxon. Just execute the query
<doc>{doc/Header, for $i in 1 to 100000 return doc/Transaction, doc/Footer}</doc>
on the supplied input document, assuming <doc> as the outer wrapper element.

Stuck with JDOM Parsing?

I have a complex JDOM element like following (A), I need to change the structure like (B), for working on JAXB (Using with already existing classes,
only thing I can do is changing the structure of xml), Can I able to do this using JDOM api?
As I am a beginer in java, it is very difficult for me, if anyone point-out a solution, it is very much helpful for me
Existing element (A)
<DETAILS>
<ROWSET name="OPTIONS">
<ROW num="1">
<Uniqueno>1000</Uniqueno>
<ROWSET name="SUSPENCE">
<ROW num="1">
<Uniqueno>1001</Uniqueno>
<ROWSET name="PERSONS">
<ROW num="1">
<Name>60821894</Name>
<Age>44</Age>
</ROW>
<ROW num="2">
<Name>60821894</Name>
<Age>44</Age>
</ROW>
</ROWSET>
<ROWSET name="PERSONS">
<ROW num="1">
<Name>60821894</Name>
<Age>55</Age>
</ROW>
<ROW num="2">
<Name>60821894</Name>
<Age>55</Age>
</ROW>
<ROW num="3">
<Name>60821894</Name>
<Age>55</Age>
</ROW>
</ROWSET>
</ROW>
</ROWSET>
</ROW>
</ROWSET>
</DETAILS>
Required element (B)
<DETAILS>
<OPTIONS>
<Uniqueno>1000</Uniqueno>
<SUSPENCE>
<Uniqueno>1001</Uniqueno>
<PERSONS>
<Name>60821894</Name>
<Age>44</Age>
<Name>60821894</Name>
<Age>44</Age>
</PERSONS>
<PERSONS>
<Name>60821894</Name>
<Age>55</Age>
<Name>60821894</Name>
<Age>55</Age>
<Name>60821894</Name>
<Age>55</Age>
</PERSONS>
</SUSPENCE>
</OPTIONS>
</DETAILS>
May I suggest to use XSLT instead. Much easier. Start with something like this
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="DETAILS/ROWSET[#name='OPTIONS']">
<DETAILS>
<OPTIONS>
<xsl:apply-templates />
</OPTIONS>
</DETAILS>
</xsl:template>
<xsl:template match="ROW">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Looking at the xmls, these are two entirely different xmls.You need to build a xml structure similar to B dyanamically.For this, the following link will help you.
http://www.ibm.com/developerworks/java/library/j-jdom/
Hope this will help you.
You have been asking essentially the same question multiple times.
Remove XML attribute using JDOM API?
Issues in Parsing XML
If you have not yet been able to get the previous questions right, you need to take a step back and work with more basic examples before you ramp up to doing multiple element moves.
While I agree with forty-two that XSL will be a better solution in the long run, I don't think you are in a place yet where that will make things easier (for you). If you have JDOM Elements available with your data, you should figure out your Java Debugger, and inspect the Elements as you add and remove them. You need to 'play' a bit to get a better understaning of how Java, XML, and JDOM work. Right now you are asking a whole bunch of related questions that show a basic misunderstanding of what in effect are 'foundation' concepts. You need to get those foundations right before you tackle these more complex concepts.
How about you start with something simple:
XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
Document doc = new Document();
Element root = new Element("DETAILS");
doc.addContent(root);
xout.output(System.out, doc);
Element row = new Element("ROW");
root.addContent(row);
xout.output(System.out, doc);
row.detach();
xout.output(System.out, doc);
You can use the above to see how content is added, and detached from JDOM content.
Then, when you have that figured out, you can put it in loops, scans, etc. so that you can detach, and re-add content from other places in the Document hierarchy.

XPath Trouble with getting attributes

I'm having a bit of trouble with some XML in Java. The following is the result of an API call to EVE Online. How can I get the "name" and "characterID" for each row?
Frankly I just have no idea where to start with this one, so please don't ask for extra information. I just gotta know how to get those attributes.
<?xml version='1.0' encoding='UTF-8'?>
<eveapi version="1">
<currentTime>2007-12-12 11:48:50</currentTime>
<result>
<rowset name="characters" key="characterID" columns="name,characterID,corporationName,corporationID">
<row name="Mary" characterID="150267069"
corporationName="Starbase Anchoring Corp" corporationID="150279367" />
<row name="Marcus" characterID="150302299"
corporationName="Marcus Corp" corporationID="150333466" />
<row name="Dieinafire" characterID="150340823"
corporationName="Center for Advanced Studies" corporationID="1000169" />
</rowset>
</result>
<cachedUntil>2007-12-12 12:48:50</cachedUntil>
</eveapi>
Try
/eveapi/result/rowset/row/#name
and
/eveapi/result/rowset/row/#key

Categories

Resources