I'm building an android app that communicates to a web server and am struggling with the following scenario:
Given ONE line of XML in a String eg:
"<test one="1" two="2" />"
I would like to extract the values into a HashMap so that:
map.get("one") = "1"
map.get("two") = "2"
I already can do this with a full XML document using the SAX Parser, this complains when i try to just give it the above string with a MalformedUrlException: Protocol not found
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
Document doc = null;
builder = factory.newDocumentBuilder();
doc = builder.parse("<test one="1" two="2" />"); //here
I realize some regex could do this but Id really rather do it properly.
The same behaviour can be found at http://metacpan.org/pod/XML::Simple#XMLin which is what the web server uses.
Can anyone help? Thanks :D
DocumentBuilder.parse(String) treats the string as a URL. Try this instead:
Document doc = builder.parse(new InputSource(new StringReader(text)));
(where text contains the XML, of course).
Related
I'm trying to transform an XML file into a document like this:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse("C:/xml/41111208890622000144550010000000011000003066-nfe.xml");
Document document = db.parse(new InputSource(new StringReader("C:/xml/41111208890622000144550010000000011000003066-nfe.xml")));
but it is giving the error message:
Exception in thread "main" org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1;
someone knows what to do?
You're currently creating a reader containing the string
"C:/xml/41111208890622000144550010000000011000003066-nfe.xml"
and asking the DocumentBuilder to parse that as if it were XML, when it's clearly not. (I'm referring to the second parse call, which I suspect is the one in your actual code. The code you've provided wouldn't compile as you've declared document twice.)
You can create a FileInputStream or perhaps an InputStreamReader wrapped around it:
String filename = "C:/xml/41111208890622000144550010000000011000003066-nfe.xml";
try (FileInputStream input = new FileInputStream(filename))
{
Document document = db.parse(new InputSource(input));
}
(I prefer to use a stream directly, and let the parser detect the encoding.)
Now this call:
Document document = db.parse("C:/xml/...");
would nearly work and may actually work, using DocumentBuilder.parse(String) - it depends on whether parse is happy to handle a filename as a URI. (I've seen some XML APIs that are fine with that, and some that aren't.) If it doesn't work, try using the file:// scheme:
Document document = db.parse("file://C:/xml/...");
I'm trying to parse a string to xml for ISO-8859-9. My code is :
private Document stringToXML(String input)
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
builder = factory.newDocumentBuilder();
return builder.parse(new ByteArrayInputStream(input.getBytes("ISO-8859-9")));
}
if input includes just utf-8 characters, code runs correctly but input includes any special character like 'ğ' it throws "com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException:"
How can i solve this problem?
Parse a StringReader via an InputSource.
If the input contains UTF-8 characters, then it is NOT an ISO-8859-9 stream. Parse it as UTF-8 or convert it to ISO-8859-9 before trying to parse. You only ever get one character set per document, trying to mix makes the whole thing meaningless.
I am trying to build server that sends a xml file to client. I am getting info from db and wants to build from that xml file.
But I have a problem with:
DocumentBuilder documentBuilder = null;
Document doc =documentBuilder.newDocument();
I am getting NullPointerException. Here is me full code:
public void createXmlTree() throws Exception {
//This method creates an element node
DocumentBuilder documentBuilder = null;
Document doc =documentBuilder.newDocument();
Element root = doc.createElement("items");
//adding a node after the last child node of the specified node.
doc.appendChild(root);
for(int i=0;i<db.stories.size();i++){
Element child = doc.createElement("item");
root.appendChild(child);
Element child1 = doc.createElement("title");
child.appendChild(child1);
Text text = doc.createTextNode(db.stories.get(i).title);
child1.appendChild(text);
//Comment comment = doc.createComment("Employee in roseindia");
//child.appendChild(comment);
Element child2 = doc.createElement("date");
child.appendChild(child2);
Text text2 = doc.createTextNode(db.stories.get(i).date);
child2.appendChild(text2);
Element child3 = doc.createElement("text");
child.appendChild(child3);
Text text3 = doc.createTextNode(db.stories.get(i).text);
child3.appendChild(text3);
root.appendChild(child3);
Well yes, you would get a NullPointerException. You're calling a method on a null reference - very clearly, given that you've assigned the documentBuilder a null value on the line before. You need to get an instance of DocumentBuilder to start with. For example:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
of course you are getting a NullPointerException, your DocumentBuilder is null.
Try instantiating it first.
// Step 1: create a DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// Step 2: create a DocumentBuilder
DocumentBuilder db = dbf.newDocumentBuilder();
Guys are right about DocumentBuilder. But may I offer you other solution? Your servlet mostly deals with generating of XML itself, i.e. produces kind of markup. This is the purpose of JSP. You can implement simple JSP page that will actually contain template of your XML and some code that inserts dynamic data. This is much simpler and easier to maintain.
Yes, JSP typically generate HTML but no-one said that they cannot generate XML or any other text format. Just do not forget to set content type to text/xml.
Do you really need to write you XML manually?
Do you have the XSD of the XML you want to write?
Because, it would be easier to generate some classes using XJC/JAXB and use the marshaller to write your XML file.
I have a JAVA application where I am sending some xml requests and receiving xml responses. I first receive response in string and then write a file and storing this file into file system. Then while parsing the xml response file I am accessing this from file system and use some of the data for further business logic.
File file = new File("log\\XMLMessage\\LastXMLResponse.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
Now I am thinking to distribute this JAVA application via Java Web Start (JWS) application and as I know I cannot keep this file into jar file since there will be modification in this file on regular basis.
What do you suggest me to do? Can I parse the String directly (no need to store the response into file)?
Document doc = db.parse(xmlMessage);
or where can I keep this file? I don't want to show this file to the user of my application.
Take the String, make a StringReader from String, make a InputSource from StringReader, then call parse on your DocumentBuilder.
Yes, you can parse the string directly,no need to store it in a file.
Try this:
String xml = "<xml></xml>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(xml.getBytes()));
System.out.println(doc);
I've spent a while looking around on Google for a way to convert a org.w3c.dom.Document to a string representation of the whole DOM tree, so I can save the object to file system.
However all the solutions I've found use javax.xml.transform.Transformer which isn't supported as part of the Android 2.1 API. How can I do this without using this class/containing package?
Please try this code:
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse("/path/to/file.xml");
DOMImplementation domImpl = ownerDocument.getImplementation();
DOMImplementationLS domImplLS = (DOMImplementationLS)domImpl.getFeature("LS", "3.0");
LSSerializer serializer = domImplLS.createLSSerializer();
serializer.getDomConfig().setParameter("xml-declaration", Boolean.valueOf(false));
LSOutput lsOutput = domImplLS.createLSOutput();
lsOutput.setCharacterStream(output);
serializer.write(doc, lsOutput);
To avoid using Transformer you should manually iterate over your xml tree, otherwise you can rely on some external libraries. You should take a look here.