How to append an XML file in Android? - java

I'm writing an XML file to the sd card, and I need to be able to open that XML file and append data to it. How can I accomplish this? For example, my XML file is:
<items>
<item attr="value">data</item>
<item attr="value2">data 2</item>
</items>
I later need to open this XML file and append a new item to it:
<item attr="value3">data 3</item>
How can I do this?

You can use a sax parser that reads the file, outputs all elements by default and when it finds the closing {}, first insert the new item, then the closing tag.
Sax parsers are available by default in Android.
One example on how to deal with Sax at all can be found here.

What you want is to obtain a Document class version of your XML file. You can do this using a DOM Parser. From the Document class you can then manipulate it and write it back out with your modifications.
Here's code on DOM parsing.
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(myfilepath);
More information on different approaches to XML in Android can be found here.

Related

How to use java to get element of xml document, but in xml string format?

I have read some links on parsing xml document like below:
<inventory>
<book year="2000">
<title>Snow Crash</title>
<author>Neal Stephenson</author>
<publisher>Spectra</publisher>
<isbn>0553380958</isbn>
<price>14.95</price>
</book>
<book year="2005">
<title>Burning Tower</title>
<author>Larry Niven</author>
<author>Jerry Pournelle</author>
<publisher>Pocket</publisher>
<isbn>0743416910</isbn>
<price>5.99</price>
</book>
<!-- more books... -->
</inventory>
using DOM parsing:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(<uri_as_string>);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile(<xpath_expression>);
however, their purpose are mostly to get VALUE of some node(s) by tag or by attribute from the document.
My purpose is to get the entire XML STRING of the node(s) back. For example, using Xpath /inventory/book[#year='2005'], i want to get the following xml back in a single string, i.e.
<book year="2005">
<title>Burning Tower</title>
<author>Larry Niven</author>
<author>Jerry Pournelle</author>
<publisher>Pocket</publisher>
<isbn>0743416910</isbn>
<price>5.99</price>
</book>
What is the API used for this purpose? And do i even need the DOM parsing in this case? Thanks,
COMMENT:
Maybe I should emphasize that I am asking this question as a XML related one, not a text file processing question. Concepts like 'tag', 'attribute', 'Xpath' still apply. The DOM model is not totally irrelevant. It's just that instead of getting the 'element' or value of a node, i want to get the whole node.
The given answers can not solve problems like: how to get a node in xml string format, given the node's Xpath representation, such as //book or /inventory/book[1]?
DOM parsers are designed to get values from the them not for actual file content.
You can use a simple file reader instead of XML.
Read line by line using a simple FileReader and check the line for the Condition and if the condition is met start the read content to concat as you want until the End of the node .
You can do it as
if(lineReadFromFile=="Your String Condition"){
//collect the desired file content here untill the end of the Node is found
}
You can simply read XML from file (consider it to be a normal text file) using FileReader. Simple apply the condition for example :
if(line.equals("<book year="2005"><title>Burning Tower</title>")) {
// retrieve/save the required content
}

How to remove duplicate XML declaration

I am receiving following XML response via Jersey client
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><aaa><bbb key="Data"><?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<my-data xsi:noNamespaceSchemaLocation="MyData.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<data name="abc" uniqueId="4fe95637-a381-4e0c-bf7f-49f794df5f23">
<variable var1="xyz" value="44"/>
</data>
</my-data>
</bbb></aaa>
I am saving this as an XML file and getting 'premature end of file' error during parsing, since the XML is malformed (duplicate XML declarations)...is there a way to remove following duplicate entry from the output?
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
Following is my Java code snippet:
String output = response.getEntity(String.class);
file = writeResponseToFile(output,"MyData.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(file); //Error
Ideally, you should fix the problem at the source. What you're receiving is not XML because having more than one XML declaration violates XML's basic grammar, making the data not well-formed.
If it is impossible to properly fix the problem at the source, and you wish to attempt repair, you have to treat that data as text, not XML, until you remove the extra XML declaration (via text-level operations, not XML parsing).
Fix the xml that you are receiving. You receive two declarations in the xml.
The xml is malformed. Remember in Jersey, you can receive files on JSON, xml, html, etc, via annotations, with #Produces.
And remember that you have xml validators on internet, to valid your xml.
Regards.

java XML parsing, the markup must be well-formed

My XML file is in the following format:
<top>
<name></name>
<title></title>
<time></time>
</top>
<top>
...
</top>
<top>
...
</top>
I write the following code to read the xml file:
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new File(QUERY_FILE)); //LINE (*)
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("top");
But the problem is I get error as at line (*):
The markup in the document following the root element must be
well-formed.
It seems that error is because I have multiple root elements in the xml file. One solution could be I add maybe <doc></doc> outside all <top> elements. But is there any other way that I can directly read in such XML file as element arrays?
You can try to isolate each<top> element and trying to parse them separately, but that's a more troublesome solution than just wrapping <doc></doc> around the xml content..
One thing I've done in the past is instead of putting the root tags in the file itself, I just read the text into a string, and wrap the <doc></doc> tags around the string before I load the XML.
You are add this line for well-formed :
<?xml version="1.0" encoding="UTF-8"?> <!-- this line-->
<top>
<name></name>
<title></title>
<time></time>
</top>
Use this page to see if your document is correct, since it is the one that sets the standard for this metalanguage.
http://validator.w3.org/#validate_by_input
Validate xml dtd, etc ..
The World Wide Web Consortium (W3C) is the main international standards organization for the World Wide Web (abbreviated WWW or W3).| Font Wikipedia

I need to parse non well-formed xml data (HTML)

I have some non well-formed xml (HTML) data in JAVA, I used JAXP Dom, but It complains.
The Question is :Is there any way to
use JAXP to parse such documents ??
I have a file containing data such as :
<employee>
<name value="ahmed" > <!-- note, this element is not closed, So it is not well-formed xml-->
</employee>
You could try running your document through the jtidy API first - that has the ability to convert html into valid xhtml: http://jtidy.sourceforge.net/howto.html
Tidy tidy = new Tidy();
tidy.setXHTML(true);
tidy.parse(......)...
You could use TagSoup. I have used it with great success. It is completely compatible with the Java XML APIs, including SAX, DOM, XSLT, and StAX. For example, here is how I used it to apply XSLT transforms to particularly poor HTML:
public static void transform(InputStream style, InputStream data)
throws SAXException, TransformerException {
XMLReader reader =
XMLReaderFactory.createXMLReader("org.ccil.cowan.tagsoup.Parser");
Source input = new SAXSource(reader, new InputSource(data));
Source xsl = new StreamSource(style);
Transformer transformer =
TransformerFactory.newInstance().newTransformer(xsl);
transformer.transform(input, new StreamResult(System.out));
}
Not really. JAXP wants well-formed markup. Have you considered the Cyberneko HTML Parser? We've been very successful with it at our shop.
EDIT: I see you are wanting to parse XML too. Hrmm.... Cyberneko works well for HTML but I don't know about others. It has a tag balancer that would close some tags off, but I don't know if you can train it to recognize tags that are not HTML.

XML Editor in java(jsp,sevlet)

I am developing xml editor using jsp and servlet. In this case i am using DOM parser.
I have one problem in XML editor ,
How to edit the following xml file without losing elements.
eg:
<book id="b1">
<bookbegin id="bb1">
<para id="p1">This is<b>first</b>line</para>
<para id="p2">This is<b>second</b>line</para>
<para id="p3">This is<b>third</b>line</para>
</bookbegin>
</book>
I try to edit the above xml file using dtd using jsp,servlet. but while i read the textvalue from xml, it return only first,second,third.How to read the 'This is' and 'line '. Then how to store back to the xml file using xpath.
thank in advance.
The <b> tag inside the <para> tag is another element, not a formatting tag (in XML). Therefore, you need to traverse down to it.
Like #JRL says, the <b> tags are cosnidered as well-formed XML and, as a consequence, splitted by your DOM processor.
I think youf ail to read other text elements because you only read text when an XML node has no more XML node, which is not your case here.

Categories