Parse simple XML document from URL to String variable - java

I am attempting to read XML from a server on http://localhost:8000, into a string variable.
The layout of the XML document is very simple, and when directing to http://localhost:8000, the following is displayed:
<result>Hello World</result>
Is there a simple way to parse this into a String variable from the localhost URL, so that for example, if I was to run:
System.out.println(XMLVariable)
(where XMLVariable is the string variable in which the content was stored in) that the output to the command line would simply be "Hello World"?

You need to parse the response from the server into an XML data structure of some sort.
The easiest way that I'm aware of (in Java) to do that is to use dom4j.
It can be as simple as this...
SAXReader reader = new SAXReader();
Document document = reader.read("http://localhost:8000/");
System.out.println(document.getText());

You can use StAX for parsing the response:
private Optional<String> extractResultValue(String xml) throws XMLStreamException {
final XMLInputFactory factory = XMLInputFactory.newInstance();
final XMLEventReader reader = factory.createXMLEventReader(new StringReader(xml));
while (reader.hasNext()) {
XMLEvent event = reader.nextEvent();
if (event.isCharacters()) {
return Optional.ofNullable(event.asCharacters().getData());
}
}
return Optional.empty();
}
Example call:
extractResultValue("<Your data from server>")
extractResultValue("<result>Hello World</result>") // Optional[Hello World]
extractResultValue("<result></result>") // Optional.empty
extractResultValue("<test>value</test>") // Optional[value]

Related

How to append XML (String) to XmlEventWriter (StAX) which already created the start of document

In order to create big XML files, we decided to make use of the StAX API. The basic structure is build by using the low-level api's: createStartDocument(), createStartElement(). This works as expected.
However, in some cases we like to append existing XML data which resides in a String (retrieved from database). The following snippet illustrates this:
import java.lang.*;
import java.io.*;
import javax.xml.stream.*;
public class Example {
public static void main(String... args) throws XMLStreamException {
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
StringWriter writer = new StringWriter();
XMLEventWriter eventWriter = outputFactory.createXMLEventWriter(writer);
eventWriter.add(eventFactory.createStartDocument("UTF-8", "1.0"));
eventWriter.add(eventFactory.createStartElement("ns0", "http://example.org", "root"));
eventWriter.add(eventFactory.createNamespace("ns0", "http://example.org"));
//In here, we want to append a piece of XML which is stored in a string variable.
String xml = "<fragments><fragment><data>This is pure text.</data></fragment></fragments>";
eventWriter.add(inputFactory.createXMLEventReader(new StringReader(xml)));
eventWriter.add(eventFactory.createEndDocument());
System.out.println(writer.toString());
}
}
With the above code, depending on the implementation, we are not getting the expected result:
Woodstox: The following exception is thrown:'Can not output XML declaration, after output has already been done'. It seems that the XMLEventReader starts off with a startDocument event, but since a startDocument event was already triggered programatically, it throws the error.
JDK: It appends <?xml version="1.0" ... <fragments><fragment>... -> Which leads to invalid XML.
I have also tried to append the XML by using:
eventFactory.createCharacters(xml);
The problem here is that even though the XML is appended, the < and > are transformed into &lt and &gt. Therefore, this results in invalid XML.
Am I missing an API that allows me to simply append a String as XML?
You can first consume any StartDocument if necessary:
String xml = "<fragments><fragment><data>This is pure text.</data></fragment></fragments>";
XMLEventReader xer = inputFactory.createXMLEventReader(new StringReader(xml));
if (xer.peek().isStartDocument())
{
xer.nextEvent();
}
eventWriter.add(xer);

converting xml to java objects with xstream in java

I have an xml ans i want to make it objects , i am using xsteam for this and I have added xstream jars in my classpath..
below is my xml...
<Eurexflows xmlns:eur="http://www.eurexchange.com/EurexIRSFullInventoryReport" xmlns:fpml="http://www.fpml.org/FpML-5/confirmation">
<EurexMessageObject>
<CCPTradeId>109599</CCPTradeId>
<novDateTime>2012-02-15 10:59:00.0</novDateTime>
</EurexMessageObject>
<EurexMessageObject>
<CCPTradeId>122270</CCPTradeId>
<novDateTime>2012-06-29 18:59:00.0</novDateTime>
</EurexMessageObject>
</Eurexflows>
below is my pojo...
public class EurexMessageObject {
private Long CCPTradeId;
private String migratedDate;
public Long getCCPTradeId() {
return CCPTradeId;
}
public void setCCPTradeId(Long cCPTradeId) {
CCPTradeId = cCPTradeId;
}
public String getMigratedDate() {
return migratedDate;
}
public void setMigratedDate(String migratedDate) {
this.migratedDate = migratedDate;
}
}
and in my main class I have coded this way..
String xmlInputtra="C:\\Rahul\\InputXml\\Xmloutput.xml";
try
{
// get XStream instance and set required aliases
XStream xstream = new XStream();
xstream.alias("EurexMessageObject", com.rbos.gdspc.eurex.EurexMessageObject.class);
// prepare cash flow message from xslt output
EurexMessageObject eurexflowMsg = (EurexMessageObject) xstream.fromXML(xmlInputtra);
System.out.println(eurexflowMsg.toString());
}catch(Exception e)
{
e.printStackTrace();
}
now upon debuging I am getting the following exception..please advise how can I overcome from this
com.thoughtworks.xstream.io.StreamException: : only whitespace content allowed before start tag and not C (position: START_DOCUMENT seen C... #1:1)
Well,the thing that is overlooked here is how you are reading in the XML file.you are using the method fromXML which is expecting the actual XML input and not the file name. So when it parses your xml (which is "Xmloutput.xml" not the actual xml)
I suggest you to use a FileReader/BufferedReader in order to get the contents of the XML back. Something like this should work:
XStream instream = new XStream();
BufferedReader br = new BufferedReader(new FileReader("Xmloutput.xml"));
StringBuffer buff = new StringBuffer();
String line;
while((line = br.readLine()) != null){
buff.append(line);
}
EurexMessageObject eurexflowMsg = (EurexMessageObject)instream.fromXML(buff.toString());
I hope it will help you, best regards.
Here path for XML file:
String xmlInputtra="C:\\Rahul\\InputXml\\Xmloutput.xml";
is treated as XML contents,
so you need to pass as String for that you can read file and pass to constructor.

How to get individual attribute from the XML file in a simpler way

I am trying to send XML file to one of my Servlet class and I am able to do that. Below is my XML file-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<request id="a487bd863c3e4513a7893966f8e186f1">
<app hash="sha1"/>
</request>
And following is my Servlet doPost method in which I need to parse the XML file and get id and hash value from that XML file.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String line;
BufferedReader br = new BufferedReader(request.getReader());
while ((line = br.readLine()) != null) {
System.out.println(line);
// now here parse the line and get `id and hash value`
// from it.
}
}
I am thinking what is the best way to get id and hash value from that XML file. I know one way is to parse the XML file and get the id and hash value. Is there any easy or direct way to get what I am looking for?
Any simple example will be appreciated.
try XPath
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
String id = xPath.evaluate("/request/#id",
new InputSource(request.getInputStream()));
If you need both id and hash then
InputStream is = request.getInputStream();
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(is);
String id = ((Element) doc.getElementsByTagName("request").item(0))
.getAttribute("id");
String hash = ((Element) doc.getElementsByTagName("app").item(0))
.getAttribute("hash");
since parsers close InpuStream we need to prevent it
InputStream is = new BufferedInputStream(request.getInputStream()) {
public void close() {
}
};
You can use sax parser or dom parser to parse xml file.

json to xml java

I want convert json to xml
here is code
public class ConvertJSONtoXML {
public static void main(String[] args) throws Exception {
InputStream is = ConvertJSONtoXML.class.getResourceAsStream("demo1.txt");
String jsonData = IOUtils.toString(is);
XMLSerializer serializer = new XMLSerializer();
JSON json = JSONSerializer.toJSON(jsonData);
String xml = serializer.write((JSON) json);
System.out.println(xml);
Here is demo1.txt
{"name":"naveed" }
It reads demo1.txt file and convert into xml but i m trying to pass json as string.
String jsonString="{\"name\":\"naveed\" }";
InputStream is = ConvertJSONtoXML.class.getResourceAsStream(jsonString);
but it wont work for string..
i thing getResourceAsStream(jsonString) doesnt work for string....
please suggest any reference
The method getResourceAsStream() actually looks on the file system for resource identified by the input string and open an input stream for it.
You should rather use something like
InputStream is = new ByteArrayInputStream( jsonString.getBytes() );
Also, you should take care of using compatible charsets.

Tagsoup fails to parse html document from a StringReader ( java )

I have this function:
private Node getDOM(String str) throws SearchEngineException {
DOMResult result = new DOMResult();
try {
XMLReader reader = new Parser();
reader.setFeature(Parser.namespacesFeature, false);
reader.setFeature(Parser.namespacePrefixesFeature, false);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new SAXSource(reader,new InputSource(new StringReader(str))), result);
} catch (Exception ex) {
throw new SearchEngineException("NukatSearchEngine.getDom: " + ex.getMessage());
}
return result.getNode();
}
It takes a String that contains the html document sent by the http server after a POST request, but fails to parse it properly - I only get like four nodes from the entire document. The string itself looks fine - if I print it out and copypasta it into a text document I see the page I expected.
When I use an overloaded version of the above method:
private Node getDOM(URL url) throws SearchEngineException {
DOMResult result = new DOMResult();
try {
XMLReader reader = new Parser();
reader.setFeature(Parser.namespacesFeature, false);
reader.setFeature(Parser.namespacePrefixesFeature, false);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new SAXSource(reader, new InputSource(url.openStream())), result);
} catch (Exception ex) {
throw new SearchEngineException("NukatSearchEngine.getDom: " + ex.getMessage());
}
return result.getNode();
}
then everything works just fine - I get a proper DOM tree, but I need to somehow retrieve the POST answer from server.
Storing the string in a file and reading it back does not work - still getting the same results.
What could be the problem?
Is it maybe a problem with the xml encoding?
This seems like an encoding problem. In the code example of yours that doesn't work you're passing the url as a string into the constructor, which uses it as the systemId, and you get problems with Tagsoup parsing the html. In the example that works you're passing the stream in to the InputSource constructor. The difference is that when you pass in the stream then the SAX implementation can figure out the encoding from the stream.
If you want to test this you could try these steps:
Stream the html you're parsing through a java.io.InputStreamReader and call getEncoding on it to see what encoding it detects.
In your first example code, call setEncoding on the InputSource passing in the encoding that the inputStreamReader reported.
See if the first example, changed to explicitly set the encoding, parses the html correctly.
There's a discussion of this toward the end of an article on using the SAX InputSource.
To get a POST response you first need to do a POST request, new InputSource(url.openStream()) probably opens a connection and reads the response from a GET request. Check out Sending a POST Request Using a URL.
Other possibilities that might be interesting to check out for doing POST requests and getting the response:
Jersey Web Client
HtmlUnit

Categories

Resources