How to create a XML object from String in Java? - java

I am trying to write a code that helps me to create a XML object. For example, I will give a string as input to a function and it will return me a XMLObject.
XMLObject convertToXML(String s) {}
When I was searching on the net, generally I saw examples about creating XML documents. So all the things I saw about creating an XML and write on to a file and create the file. But I have done something like that:
Document document = new Document();
Element child = new Element("snmp");
child.addContent(new Element("snmpType").setText("snmpget"));
child.addContent(new Element("IpAdress").setText("127.0.0.1"));
child.addContent(new Element("OID").setText("1.3.6.1.2.1.1.3.0"));
document.setContent(child);
Do you think it is enough to create an XML object? and also can you please help me how to get data from XML? For example, how can I get the IpAdressfrom that XML?
Thank you all a lot
EDIT 1: Actually now I thought that maybe it would be much easier for me to have a file like base.xml, I will write all basic things into that for example:
<snmp>
<snmpType><snmpType>
<OID></OID>
</snmp>
and then use this file to create a XML object. What do you think about that?

If you can create a string xml you can easily transform it to the xml document object e.g. -
String xmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><a><b></b><c></c></a>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xmlString)));
} catch (Exception e) {
e.printStackTrace();
}
You can use the document object and xml parsing libraries or xpath to get back the ip address.

try something like
public static Document loadXML(String xml) throws Exception
{
DocumentBuilderFactory fctr = DocumentBuilderFactory.newInstance();
DocumentBuilder bldr = fctr.newDocumentBuilder();
InputSource insrc = new InputSource(new StringReader(xml));
return bldr.parse(insrc);
}

Related

Trying to get the value of a tag in an xml string java

I have an xml string stored in a StringBuilder.
My xml looks like this
couldn't write it in code so here's a screenshot
inside the report tag, it looks like
what it looks like
I would like to get access to any tag value I want in the record tag, what I have is :
StringBuilder informationString = new StringBuilder();
Scanner scanner = new Scanner(url.openStream());
while (scanner.hasNext()) {
informationString.append(scanner.nextLine());
}
//Close the scanner
scanner.close();
System.out.println(informationString);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(String.valueOf(informationString))));
Element rootElement = document.getDocumentElement();
But I do not know what to do with this and am very lost
Thanks by advance for helping
In general, you can use the below routine
Element documentElement=....
NodeList elmList=documentElement.getElementsByTagName("elementName");
Element e=(Element)elmList.itm(x);//putting it in a loop would do
You could keep using the above to get elements recursively.
Though a better approach would be to use XPath (Saxon has a decent XPath implementaton, though there are many more libraries to choose from)

Converting XML to document in java creates null document

I'm trying to parse xml, downloaded from the web, in java, following examples from here (stackoverflow) and other sources.
First I pack the xml in a string:
String xml = getXML(url, logger);
If I printout the xml string at this point:
System.out.println("XML " + xml);
I get a printout of the xml so I'm assuming there is no fault up to this point.
Then I try to create a document that I can evaluate:
InputSource is= new InputSource(new StringReader(xml));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(is);
If I print out the document here:
System.out.println("Doc: " + doc);
I get:
Doc: [#document: null]
When I later try to evaluate expressions with Xpath I get java.lang.NullPointerException and also when just trying to get the length of the root:
System.out.println("Root length " + rootNode.getLength());
which leaves me to believe the document (and later the node) is truly null.
When I try to print out the Input Source or the Node I get eg.
Input Source: org.xml.sax.InputSource#29453f44
which I don't know how to interpret.
Can any one see what I've done wrong or suggest a way forward?
Thanks in advance.
You may need another way to render the document as a string.
For JDOM:
public static String toString(final Document document) {
try {
final ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
final XMLOutputter outp = new XMLOutputter();
outp.output(document, out);
final String string = out.toString("UTF-8");
return string;
}
catch (final Exception e) {
throw new IllegalStateException("Cannot stringify document.", e);
}
}
The output
org.xml.sax.InputSource#29453f44
simply is the class name + the hash code of the instance (as defined in the Object class). It indicates that the class of the instance has toString not overridden.

Comparing of two XML DOC is getting fail because docs is comimg from two source

I have converted a string to an XML document using the code below:
String xmlStr = "<msg><uuid>12345</uuid></msg>"
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xmlStr)));
return doc;
} catch (Exception e) {
throw new RuntimeException(e);
}
Then I converted an XML file to a document with the following:
File file = new File("src/test/resources/xmlForJunitTest.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document expectedDoc = db.parse(file);
Finally I compare the two documents:
Document actualDoc = XmlUtils.convertStringToDocument(xmlString);
Diff myDiff = new Diff(expectedDoc, actualDoc);
assert (myDiff.similar());
This test passes using an XML file (xmlForJunitTest.xml) formatted like so:
<msg><uuid>12345</uuid></msg>
And it fails with this:
<msg>
<uuid>12345</uuid>
</msg>
Please you can suggest why this failure occurs, and what the solution is?
The assertion fails because one document includes whitespace, and the other doesn't. I believe you need to look at the normalizeWhitespace flag in XmlUnit (assuming that's what you're using).

Convert a String to a xml Element java

I want to convert a String to org.jdom.Element
String s = "<rdf:Description rdf:about=\"http://dbpedia.org/resource/Barack_Obama\">";
How can I do it?
There is more than one way to parse XML from string:
Example 1:
String xml = "Your XML";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
Example 2:
Using a SAXParser which can read an inputsource:
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
saxParser.parse(new InputSource(new StringReader("Your XML")), handler);
See: SAXParser, InputSource
Create a Document from your string. Look at JDOM FAQ: How do I construct a Document from a String?
Use method Document.getRootElement() to access the root element.
(You mentioned package org.jdom so I assume you work with JDOM 1.1.)
I recommend you use the Simple XML Framework from http://simple.sourceforge.net/.With this framework you can serialize and deserialize your objects easily. I hope this information can be important for you.

How to deal with unknown entity references?

I'm parsing (a lot of) XML files that contain entity references which i dont know in advance (can't change that fact).
For example:
xml = "<tag>I'm content with &funny; &entity; &references;.</tag>"
when i try to parse this using the following code:
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final DocumentBuilder db = dbf.newDocumentBuilder();
final InputSource is = new InputSource(new StringReader(xml));
final Document d = db.parse(is);
i get the following exception:
org.xml.sax.SAXParseException: The entity "funny" was referenced, but not declared.
but, what i do want to achieve is, that the parser replaces every entity that is not declared (unknown to the parser) with an empty String ''.
Or even better, is there a way to pass a map to the parser like:
Map<String,String> entityMapping = ...
entityMapping.put("funny","very");
entityMapping.put("entity","important");
entityMapping.put("references","stuff");
so that i could do the following:
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final DocumentBuilder db = dbf.newDocumentBuilder();
final InputSource is = new InputSource(new StringReader(xml));
db.setEntityResolver(entityMapping);
final Document d = db.parse(is);
if i would obtain the text from the document using this example code i should receive:
I'm content with very important stuff.
Any suggestions? Of course, i already would be happy to just replace the unknown entity's with empty strings.
Thanks,
The StAX API has support for this. Have a look at XMLInputFactory, it has a runtime property which dictates whether or not internal entities are expanded, or left in place. If set to false, then the StAX event stream will contain instances of EntityReference to represent the unexpanded entities.
If you still want a DOM as the end result, you can chain it together like this:
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
inputFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
String xml = "my xml";
StringReader xmlReader = new StringReader(xml);
XMLEventReader eventReader = inputFactory.createXMLEventReader(xmlReader);
StAXSource source = new StAXSource(eventReader);
DOMResult result = new DOMResult();
transformer.transform(source, result);
Node document = result.getNode();
In this case, the resulting DOM will contain nodes of org.w3c.dom.EntityReference mixed in with the text nodes. You can then process these as you see fit.
Since your XML input seems to be available as a String, could you not do a simple pre-processing with regular expression replacement?
xml = "...";
/* replace entities before parsing */
for (Map.Entry<String,String> entry : entityMapping.entrySet()) {
xml = xml.replaceAll("&" + entry.getKey() + ";", entry.getValue());
}
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
...
It's quite hacky, and you may want to spend some extra effort to ensure that the regexps only match where they really should (think <entity name="&don't-match-me;"/>), but at least it's something...
Of course, there are more efficient ways to achieve the same effect than calling replaceAll() a lot of times.
You could add the entities at the befinning of the file. Look here for more infos.
You could also take a look at this thread where someone seems to have implemented an EntityResolver interface (you could also implement EntityResolver2 !) where you can process the entities on the fly (e.g. with your proposed Map).
WARNING: there is a bug! in jdk6, but you could try it with jdk5

Categories

Resources