So I've gotten help from here already so I figured why not try it out again!? Any suggestions would be greatly appreciated.
I'm using HTTP client and making a POST request; the response is an XML body that looks like the following:
<?xml version="1.0" encoding="UTF-8"?>
<CartLink
xmlns="http://api.gsicommerce.com/schema/ews/1.0">
<Name>vSisFfYlAPwAAAE_CPBZ3qYh</Name>
<Uri>carts/vSisFfYlAPwAAAE_CPBZ3qYh</Uri>
</CartLink>
Now...
I have an HttpEntity which is
[HttpResponse].getEntity().
Then I get a String representation of the response (which is XML in this case) by saying
String content = EntityUtils.toString(HttpEntity)
I tried following some of the suggestions on this post: How to create a XML object from String in Java? but it did not seem to work for me. When I built up the document it still appeared to be null.
MY END GOAL here is just to get the NAME field.. i.e. the "vSisFfYlAPwAAAE_CPBZ3qYh" part. So do I want to build up a document and then extract it...? Or is there a simpler way? I've been trying different things and I can't seem to get it to work.
Thanks for all of the help guys, it is most appreciated!!
Instead of trying to extract the value with string manipulation, try to use Java's inbuilt ability to parse XML. That's a much better approach. Http Components returns responses in an XML format - there's a reason for that. :)
Here's probably one way to solve your problem:
// Parse the response using DocumentBuilder so you can get at elements easily
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(response);
Element root = doc.getDocumentElement();
// Now let's say you have not one, but 'n' nodes that contain the value
// you're looking for. Use NodeList to get a list of all those nodes and just
// pull out the tag/attribute's value you want.
NodeList nameNodesList = doc.getElementsByTagName("Name");
ArrayList<String> nameValues = null;
// Now iterate through the Nodelist to get the values you want.
for (int i=0; i<nameNodesList.getLength(); i++){
nameValues.add(nameNodesList.item(i).getTextContent());
}
The ArrayList "nameValues" will now hold every single value contained within "Name" tags. You could also create a HashMap to store a key value pair of Nodes and their respective text contents.
Hope this helps.
Related
I have generated an xml file from an excel data base and it contains automatically an element called "offset". To make my new file match my needs, I want to remove this element using java.
here is the xml content:
<Root><models><id>2</id><modelName>Baseline</modelName><domain_id>2</domain_id><description> desctiption </description><years><Y2013>value1</Y2013><Y2014>value2</Y2014><Y2015>value3</Y2015><Y2016>value4</Y2016><Y2017>value5</Y2017></years><offset/></models></Root>
I made a code that reads(with a buffered reader) and writes the content in a new file and used the condition if:
while (fileContent !=null){
fileContent=xmlReader.readLine();
if (!(fileContent.equals("<offset/>"))){
System.out.println("here is the line:"+ fileContent);
XMLFile+=fileContent;
}
}
But it does not work
I would personally recommend using a proper XML parser like Java DOM to check and delete your nodes, rather than dealing with your XML as raw Strings (yuck). Try something like this to remove your 'offset' node.
File xmlFile = new File("your_xml.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
NodeList nList = doc.getElementsByTagName("offset");
for (int i = 0; i < nList.getLength(); i++) {
Node node = nList.item(i);
node.getParentNode().removeChild(node);
}
The above code removes any 'offset' nodes in an xml file.
If resources/speed considerations are an issue (like when your_xml.xml is huge), you would be better off using SAX, which is faster (a little more code intensive) and doesn't store the XML in memory.
Once your Document has been edited you'll probably want to convert it to a String to parse to your OutputStream of choice.
Hope this helps.
Just try to replace the unwanted string with an empty string. It is quick... and seriously dirty. But might solve your problem quickly... just to reappear later on ;-)
fileContent.replace("<offset/>, "");
String sXML= "<Root><models><id>2</id><modelName>Baseline</modelName><domain_id>2</domain_id><description> desctiption </description><years><Y2013>value1</Y2013><Y2014>value2</Y2014><Y2015>value3</Y2015><Y2016>value4</Y2016><Y2017>value5</Y2017></years><offset/></models></Root>";
System.out.println(sXML);
String sNewXML = sXML.replace("<offset/>", "");
System.out.println(sNewXML);
String xml = "<Root><models><id>2</id><modelName>Baseline</modelName><domain_id>2</domain_id><description> desctiption </description><years><Y2013>value1</Y2013><Y2014>value2</Y2014><Y2015>value3</Y2015><Y2016>value4</Y2016><Y2017>value5</Y2017></years><offset/></models></Root>";
xml = xml.replaceAll("<offset/>", "");
System.out.println(xml);
In your original code that you included you have:
while (fileContent !=null)
Are you initializing fileContent to some non-null value before that line? If not, the code inside your while block will not run.
But I do agree with the other posters that a simple replaceAll() would be more concise, and a real XML API is better if you want to do anything more sophisticated.
I have store in a String variable(link) the url that I get the xml response, I use a dom to parse the xml data.
In order to be sure that I extract the data correctly I store the xml in the local drive, build my parser and I took the data:
document = builder.parse(new File(filepath));
So when I try to get it from url I used:
document = builder.parse(new URL(link).openStream());
And it didn't work. What am I missing?
The data of the xml are stored in a list which then are shown in a jsf datatable.
Well the above works just fine, the problem was the index of elements of the nodelist. For some reason when i was reading from file
obj.setattribute1(cDetails.item(1).getTextContent());
obj.setattribute2(cDetails.item(3).getTextContent());
see that the item are increased by 2 each time
now that i read a URL the increment is 1 every time
Now i am sure that there is a reason for this which i don't understand probably cause of my limited yet knowledge but the above work and the index of the item increases 1 for the next item in the nodelist.
I have a string which has an xml inside. I want to write this to a Document in java so i can later retrieve the attributes within it and store them in other strings. Could someone provide me with an example of this please?
Some more details are necessary for a proper answer but you can start with the DocumentBuilder like this:
DocumentBuilder db = DocumentBuilderFactory.newDocumentBuilder()
Document doc = db.parse(yourstring);
You now have a Document from which you can access your XML attributes etc.
Check out http://www.java-tips.org/java-se-tips/javax.xml.parsers/how-to-read-xml-file-in-java.html. Hopefully it will give you a good starting point.
http://www.java-samples.com/showtutorial.php?tutorialid=152
This is a good example of how to parse out some XML. This should be a good start for you.
Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(myXMLString.getBytes());
I need to find list of near by theaters depending upon user zipcode input, I have an api which gives this information if we pass zipcode but am not sure as to how to use this api, this is my first time trying to get data from api and am not familiar with atom, pox and ast acronyms.
API that gives theater information is located at http://gateway.moviefone.com/, any guidance suggestion would be highly appreciate to get started with using this api and understanding about how to work with api's.
There's several steps involved, here's some pseudocode to help you get started:
String zip = "...";
String url = "http://gateway.moviefone.com/movies/pox/closesttheaters.xml?zip=" + zip;
// read and parse the xml
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(url);
//get elements you need
NodeList list = document.getElementsByTagName("closestTheatersUrl");
String urlForTheater = list.item(0).getNodeValue();
I have this XML file which doesn't have a root node. Other than manually adding a "fake" root element, is there any way I would be able to parse an XML file in Java? Thanks.
I suppose you could create a new implementation of InputStream that wraps the one you'll be parsing from. This implementation would return the bytes of the opening root tag before the bytes from the wrapped stream and the bytes of the closing root tag afterwards. That would be fairly simple to do.
I may be faced with this problem too. Legacy code, eh?
Ian.
Edit: You could also look at java.io.SequenceInputStream which allows you to append streams to one another. You would need to put your prefix and suffix in byte arrays and wrap them in ByteArrayInputStreams but it's all fairly straightforward.
Your XML document needs a root xml element to be considered well formed. Without this you will not be able to parse it with an xml parser.
One way is to provide your own dummy wrapper without touching the original 'xml' (the not well formed 'xml') Need the word for that:
Syntax
<!DOCTYPE some_root_elem SYSTEM "/home/ego/some.dtd"
[
<!ENTITY entity-name "Some value to be inserted at the entity">
]
Example:
<!DOCTYPE dummy [
<!ENTITY data SYSTEM "http://wherever-my-data-is">
]>
<dummy>
&data;
</dummy>
You could use another parser like Jsoup. It can parse XML without a root.
I think even if any API would have an option for this, it will only return you the first node of the "XML" which will look like a root and discard the rest.
So the answer is probably to do it yourself. Scanner or StringTokenizer might do the trick.
Maybe some html parsers might help, they are usually less strict.
Here's what I did:
There's an old java.io.SequenceInputStream class, which is so old that it takes Enumeration rather than List or such.
With it, you can prepend and append the root element tags (<div> and </div> in my case) around your no-root XML stream. (You shouldn't do it by concatenating Strings due to performance and memory reasons.)
public void tryExtractHighestHeader(ParserContext context)
{
String xhtmlString = context.getBody();
if (xhtmlString == null || "".equals(xhtmlString))
return;
// The XHTML needs to be wrapped, because it has no root element.
ByteArrayInputStream divStart = new ByteArrayInputStream("<div>".getBytes(StandardCharsets.UTF_8));
ByteArrayInputStream divEnd = new ByteArrayInputStream("</div>".getBytes(StandardCharsets.UTF_8));
ByteArrayInputStream is = new ByteArrayInputStream(xhtmlString.getBytes(StandardCharsets.UTF_8));
Enumeration<InputStream> streams = new IteratorEnumeration(Arrays.asList(new InputStream[]{divStart, is, divEnd}).iterator());
try (SequenceInputStream wrapped = new SequenceInputStream(streams);) {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(wrapped);
From here you can do whatever you like, but keep in mind the extra element.
XPath xPath = XPathFactory.newInstance().newXPath();
}
catch (Exception e) {
throw new RuntimeException("Failed parsing XML: " + e.getMessage());
}
}