how to get data from xml object in org.jdom.Document? - java

I am trying to get some datas from xml document object. My imaginery xml file is like that;
<root>
<body>
<oids>
<oid> </oid>
<oid> </oid>
<oid> </oid>
<oid> </oid>
</oids>
</body>
</root>
And to do that I am writing a function for that ;
public Vector<String> getOIDs(Document document){
Vector<String> oids = new Vector<String>();
Element root = document.getRootElement();
Element body = root.getChild("body");
Element element = body.getChild("oids");
List rows = (List) element.getChildren("oid");
/*
List rows = root.getChildren("oids");
for (int i = 0; i < rows.size(); i++) {
}
*/
return oids;
}
As I read from the Internet , I undeerstood that I should use List class to get the s but when I try it, I always get errors. Can you please help me to get the s.
Thank you all.

I can't see what is wrong in the code. The only thing that looks fishy is the explicit conversion to List. Why is that?
I'm guessing that you have imported the wrong List implementation. Make sure you have imported java.util.List.

In your XML, <body> and <oids> are siblings, i.e. they have the same parent. Your code assumes that <oids> is a child of <body>. That should hopefully get you going again.

Related

xpath compile using java - NodeList with particular node value

<data xmlns:fsd="abc.org" xmlns:xlink="http://www.w3.org/1999/xlink">
<meta name="elapsed-time" value="46" />
<org-family>
<family-member id="5">
<publication-reference>
<document-id document-id-type="docdb">
<country>US</country>
<doc-number>3056228</doc-number>
<date>20160817</date>
</document-id>
</publication-reference>
</family-member>
<family-member id="2">
<publication-reference>
<document-id document-id-type="docdb">
<country>US</country>
<doc-number>2013315173</doc-number>
<date>20150430</date>
</document-id>
</publication-reference>
</family-member>
</org-family>
</data>
From the above xml i want to extract country and date node value, below are my java code
NodeList familyMembers = (NodeList) xPath.compile("//family-member//publication-reference//document-id[#document-id-type=\"docdb\"]//text()").evaluate(xmlDocument,XPathConstants.NODESET);
ArrayList mainFamily = new ArrayList();
for (int i = 0; i < familyMembers.getLength(); i++) {
mainFamily.add(familyMembers.item(i).getNodeValue());
}
but its extract all the three node value (country, doc-number and date), but i need only the two node value (country and date), in the for loop how should i pass the requested node value?
Once you selected a document-id node, the // operator selects its ALL descendants,
then text() converts each of them into a string. If you want to process only some of the descentant nodes, just list them (build an explicit sequence of sub-elements).
You can also get rid of expensive (and superfluous here!) // operators.
Try replacing the query with
"//family-member/publication-reference/document-id[#document-id-type=\"docdb\"]/(country, date)/text()"

Jsoup not matching tags without certain attributes?

I have a function that, given a div element, will find all img elements within it.
The only problem is that only the first 3 are being selected. The only difference between the first 3 and the rest is the inclusion of attributes (class and alt)
Document doc = Jsoup.connect("http://www.dhgate.com/wholesale/kitchen-fixtures/c019034002-1.html").get();
Elements elements = doc.select("div.prolist");
for (Element e : elements) {
String img[] = getImagesSrc(e, 1);
}
....
protected String[] getImagesSrc(Element e, int numOfImages) {
String src[];
src = new String[numOfImages];
int i = 0;
Elements imgElements = e.select("img[src]");
for (Element o : imgElements) {
System.out.println("html = " + o.outerHtml());
src[i++] = o.attr("src");
}
return src;
}
Some example div element (These are what gets passed to the function)
<div class="prolist">
<img class="folder" alt="Folder" src="folder.jpg"/>
</div>
<div...
...div>
<div class="prolist">
<img src="folder.jpg"/>
</div>
Shouldn't I be getting all images regardless of the sttributes?
I have tested the code using the same HTML structure from the website and from localhost. The code DOES work on locahost but NOT on the website (www.dhgate.com)
SOLVED - The site was using lazyload plugin so the HTML in the inspector was reading different from what Jsoup was. In my case I had to include 'a' tags that had [class~=lazyload]
The program does get the source of all img tags inside a div element with class prolist. But you should take into account some issue that may occur depending on you complete program.
for (Element e : elements) {
String img[] = getImagesSrc(e, 1);
}
In the first loop the img array is overwritten on each iteration. So if you have multiple div elements with class prolist, the img tag array of each will overwrite the other. If you want to get the entire img or all div tags change the getImagesSrc() method argument to Elements and pass doc.select("div.prolist") directly.
The second argument for getImagesSrc() method is used to initialze the array. So in case if we have more than one img tags it will result in an ArrayOutOfBoundException. The number of image tags are indetermisnistic. So you should use a List in this case. If you want an array you can later make an array out of the list. For e.g
protected String[] getImagesSrc(Element e) {
List<String> imgSources = new ArrayList<String>();
Elements imgElements = e.select("img[src]");
for (Element o : imgElements) {
imgSources.add(o.attr("src"));
}
return imgSources.toArray(new String[imgSources.size()]);
}
Also note that since you are slecting img like e.select("img[src]");, it'll only return img tags that has an src attribute.

How to add all row elements in database to JSON object

I'm trying to retrieve all elements in database and display in webpage.But with my code it able to retrieve only one row element. Problem is, it retrieves all element but it adds the last row element to the object. I think all elements retrieved first are overwritten Because of that it displays last row element. Can anyone tell me how add all row elements to the JSON object. Please help me.
code :
while(rs.next()){
ImageFile.setName(rs.getString("imagename").trim());
ImageFile.setDisc(rs.getString("imagedisc").trim());
ImageFile.setImageid(rs.getInt("imageid"));
ImageFile.setalbumid(rs.getInt("albumid"));
byte imageData[] = rs.getBytes("imagethumb");
String encoded = DatatypeConverter.printBase64Binary(imageData);
ImageFile.setThumb(encoded);
byte image1Data[] = rs.getBytes("imagethumb");
String encoded1 = DatatypeConverter.printBase64Binary(image1Data);
ImageFile.setFull(encoded1);
}
The complete source code is in this question
Please help me........Thanks....
Use a list Collection to keep all the row-values of db, like - List<ImageFileInfo> which denotes List containing of ImageFileInfo Objects . And then serialize the list to json String.
List<ImageFileInfo> imageFileList = new ArrayList<ImageFileInfo>();
while(rs.next()){
ImageFileInfo info = new ImageFileInfo();
info..setName(rs.getString("imagename").trim());
...
imageFileList.add(info);
}
Json serialization -
Type typeOfList= new TypeToken<List<ImageFileInfo>>(){}.getType();
String s = gson.toJson(imageFileList , typeOfList);

Getting value of XML node

I know how to parse XML documents with DOM when they are in the form:
<tagname> valueIWant </tagname>
However, the element I'm now trying to get is instead in the form
<photo farm="9" id="8147664661" isfamily="0" isfriend="0" ispublic="1"
owner="8437609#N04" secret="4902a217af" server="8192" title="Rainbow"/>
I usually use cel.getTextContent() to return the value, but that doesn't work in this case. Neither does cel.getAttributes(), which I thought would work...
Ideally, I need to just get the id and owner numerical values. However if someone can help on how to get all of it, then I can deal with removing the parts I don't want later.
What you're looking to retrieve is the value of different attributes that are attached with an Element. Look at using the getAttribute(String name) method to achieve this
If you want to retrieve all the attributes, all you can do so using getAttributes() and iterate through it. An example of both of these methods might be something like this:
private void getData(Document document){
if(document == null)
return;
NodeList list = document.getElementsByTagName("photo");
Element photoElement = null;
if(list.getLength() > 0){
photoElement = (Element) list.item(0);
}
if(photoElement != null){
System.out.println("ID: "+photoElement.getAttribute("id"));
System.out.println("Owner: "+photoElement.getAttribute("owner"));
NamedNodeMap childList = photoElement.getAttributes();
Attr attribute;
for(int index = 0; index < childList.getLength(); index++){
if(childList.item(index).getNodeType() == Node.ATTRIBUTE_NODE){
attribute = ((Attr)childList.item(index));
System.out.println(attribute.getNodeName()+" : "+attribute.getNodeValue());
}else{
System.out.println(childList.item(index).getNodeType());
}
}
}
}
Something like:
Element photo = (Element)yournode;
photo.getAttribute("farm");
will get you the value of the farm attribute. You need to treat your node as an Element to have access to these attributes (doc).

help with grails map

I'm trying to dynamically create a map collection but I am still new to grails and was hoping someone could help me. What I want to do is parse and xml file and add the values to a map. I've got the parsing down, but just dont know how to dynamically add the node values to the map. here's what i have so far:
example xml stream:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<connections total="29">
<person>
<id>123245</id>
<first-name>me</first-name>
<last-name>you</last-name>
</person>
</connections>
</person>
I then parse it like this:
def alum = new XmlSlurper().parseText(xmlResponse)
alum.connections.person.each{ conName ->
print conName.'id'.toString() + " " + conName.'first-name'.toString() + " " + conName.'last-name'.toString() + "\n"
}
So, this allows me to iterate over, and parse, the xml stream. my question is, if i wanted to add the values, dynamically, to a map like this:
def myMap= [fName:"SomeName", lName:"Sme last Name", id:1234]
how would i do this?
Thank you
jason
If you don't know the child node names and want to use them as the keys in the map, use this:
def alum = new XmlSlurper().parseText(xmlResponse)
alum.connections.person.each { conName ->
def myMap = [:]
conName.children().each { child -> myMap[child.name()] = child.text() }
}
This will result in [id: '123245', 'first-name': 'me', 'last-name': 'you']
Unrelated: you can shorted up your debug code with a GString:
print "${conName.'id'} ${conName.'first-name'} ${conName.'last-name'}\n"
well, i ended up just using a multidimensional array, and that seems to have worked fine. Thanks again for your help
int i=0
String[][] friends = new String[test][4]
alum.connections.person.each{ conName ->
friends[i][0] =conName.'id'.toString()
friends[i][1] =conName.'first-name'.toString()
friends[i][2] =conName.'last-name'.toString()
friends[i][3] =conName.'picture-url'.toString()
i++
}
[Friends:friends]
This way, i was able to pass it on to my groovy page and iterate over the array

Categories

Resources