Parse nested xml in java

How to read nested elements in xml with dom parser or whatever

I want to read nested elements and assign all elements and datas to two dimensional array. In the following xml example, the elements are ,,,,, and the datas are m111,m22,m3 . I want to transfer to 2D array like that is String array[][] = ,,>; Thanks.

Why not to convert XML to a Java Object, where the Java Object would be a wrapper class for the 2D array? Then you could use ready tools, for instance JAXB. Have a look at this post javarevisited.blogspot.co.uk/2013/01/…

I don’t want to give root_element_name, node_element_name and other element_names in xml document. I want to get all element names by the program sensing auto.

1 Answer 1

I have solved. It was a very complex.

Content-1AContent-2BContent-3CContent-4DContent-5EContent-6FContent-7G 
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class XmlReader1 < public XmlReader1() < try < String str = ""; String strAdd; String bR = "<(?!/)(.*?)>"; String pR = ">(?!<)(.*?)<(/.*?)>"; File file = new File("E:\\test\\b.xml"); BufferedReader br = null; int s1 = 0; int s2 = 0; int s3 = 0; int s31 = 0; int mb = 0; int mp = 0; //dosyadan verinin çekilip str stringine atanması. br = new BufferedReader(new FileReader(file)); while ((strAdd = br.readLine()) != null) < str += strAdd; >Pattern pattern1 = Pattern.compile(bR); Matcher matcher1 = pattern1.matcher(str); Pattern pattern2 = Pattern.compile(pR); Matcher matcher2 = pattern2.matcher(str); Pattern pattern3 = Pattern.compile(bR); Matcher matcher3 = pattern3.matcher(str); Pattern pattern4 = Pattern.compile(pR); Matcher matcher4 = pattern4.matcher(str); //dosyadaki elementlerin() sayılması. while (matcher1.find()) < mb++; >//dosyadaki çocuk elementlerin(child) sayılması. while (matcher2.find()) < mp++; >//elementler dizisi. String mB[] = new String[mb]; //çocuk elemanlar dizisi. String mP[] = new String[mp]; //dosyadaki elementlerin mP[] dizisine atanması. while (matcher4.find()) < mP[s2] = matcher4.group(1); s2++; >//dosyadaki çocuk elemanların mB[] dizisine atanması. while (matcher3.find()) < mB[s1] = matcher3.group(1); s1++; >//dom parser işlemleri. DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new FileInputStream(file)); NodeList nL = doc.getElementsByTagName(doc.getDocumentElement().getNodeName()); Node nD = nL.item(0); Element eL = (Element) nD; int big[] = new int[mp]; //element gruplarının kaç kişi olduğunun bulunması. for (int i = 0; i < mp; i++) < for (int j = 1; j < mb; j++) < String a = eL.getElementsByTagName(mB[j]).item(0).getTextContent(); String b = mP[i]; if (a.equals(b)) < s3++; >> big[i] = s3; s3 = 0; > //2 boyutlu ana dizinin dinamik sütun sayıları belirtilmeden tanımlanması. String add[][] = new String[mp][]; //ana diziye element ve elemanların birbirine bağlanarak atanması. for (int i = 0; i < mp; i++) < //ana dizinin sütun sayısı, her element-eleman grubunun sayısına göre oluşturulması. add[i] = new String[big[i]+1]; //ana diziye elementleri ekleme işlemi. for (int j = 1; j < mb; j++) < //verilen mB[] dizisindeki elementin ismine göre, o elementin çocuğunun bulunması. String a = eL.getElementsByTagName(mB[j]).item(0).getTextContent(); //çocuk elemanlar dizisi. String b = mP[i]; //String a'daki ortak çocuğa sahip elementlerin aynı dalda gruplandırılması. if (a.equals(b)) < add[i][s3] = mB[j]; s3++; >> //gruplanan elementlere çocukların eklenmesi. add[i][s3] = mP[i]; s3 = 0; > //ana dizinin yazdırılması. for (int i = 0; i < add.length; i++) < for (int j = 0; j < add[i].length; j++) < System.out.println(add[i][j]); >> > catch (Exception e) < System.err.println("Hata!"); >> public static void main(String[] args) < XmlReader1 x = new XmlReader1(); >> 
A_1.1 A_1.2 A_1.3 A_1.4 A_1.5 A_1.6 A_1.7 Content-1A B_2.1 B_2.2 B_2.3 B_2.4 B_2.5 Content-2B C_3.1 C_3.2 C_3.3 C_3.4 C_3.5 C_3.6 C_3.7 C_3.8 C_3.9 C_3.10 Content-3C D_4.1 D_4.2 D_4.3 Content-4D E_5.1 Content-5E F_6.1 F_6.2 Content-6F G_7.1 G_7.2 G_7.3 G_7.4 Content-7G 

Источник

Parsing XML for deeply nested data

As you can see, I am interested in two elements, the first of which is deeply nested within the root element, and the second of which is deeply nested within that first element. There are multiple (sibling) elementIAmInterestedIn and otherElementIAmInterestedIn elements in the document. I want to parse this XML file with Java and put the data from all the elementIAmInterestedIn and otherElementIAmInterestedIn elements into either a data structure or Java objects — it doesn’t matter much to me as long as it is organized and I can access it later. I’m able to write a recursive DOM parser method that does a depth-first traversal of the XML so that it touches every element. I also wrote a Java class with JAXB annotations that represents elementIAmInterestedIn. Then, in the recursive method, I can check when I get to an elementIAmInterestedIn and unmarshal it into an instance of the JAXB class. This works fine except that such an object should also contain multiple otherElementIAmInterestedIn. This is where I’m stuck. How can I get the data out of otherElementIAmInterestedIn and assign it to the JAXB object? I’ve seen the @XmlWrapper annotation, but this seems to only work for one layer of nesting. Also, I cannot use @XmlPath. Maybe I should scratch that idea and use a whole new approach. I’m really just getting started with XML parsing so perhaps I’m overlooking a more obvious solution. How would you parse an XML document structured like this and store the data in an organized way?

Источник

Parse XML with nested xml opening tags in java

There is no easy way to parse that since that isn’t valid xml. But seeing that it is a soap-response it makes me wonder what service that gives it to you, wouldn’t it be better to see if they can fix the service (or if you can fix the service if you have access?).

You can try to pre-process the stream, remove the invalid part (e.g. with regular expression replacement), and then parse it with regular XML parser. I also think that you could be able to parse it using a SAX parser.

I’ve seen this a few times from soap responses — ie a response within a response — if you can html encode your response before you parse it so it becomes something like <serviceResponse> etc etc its the way forward.

You are not trying to parse XML with nested XML declarations, because XML cannot contain nested XML declarations. Rather, you are trying to parse non-XML input. So you will need a non-XML parser. It would be better to persuade the supplier of these files to generate proper well-formed XML.

4 Answers 4

I don’t think this is really a Java problem. Having a second XML declaration within the XML body is just illegal, so I don’t think you’ll be able to get any XML parsers to parse that. If you have control over the XML (it looks like you’re generating it to store a response) then you could try wrapping the inner-XML document with CDATA:

I’m thinking that you most likely don’t want the extra XML declaration inside that response at all. Do you have control over the code that creates the response? My guess is that the XML snippet . is created as a separate DOM object and then the string is spliced in the middle of the response. Writing out the entire XML document object results in the XML declaration being included, but if you just grab the document root node object ( ) and write that out as a string then it probably won’t include the extra XML declaration that’s causing you all this trouble.

Источник

Parsing nested elements in an XML file using Java

Currently, this is what my XML file looks like. There’s 10 more students, but I figured you didn’t need to see that.

 Joe Edwards 
345 North Brea CA 99999 (714) 444-4444
CIS 100 3 A CIS 111 4 B
NodeList studentlist = doc.getElementsByTagName("Student"); for(int i = 0; i < studentlist.getLength(); i++) < Node n = studentlist.item(i); Element element = (Element)n; String Student obj = new Student(id); NodeList slist = n.getChildNodes(); for (int j = 0; j < slist.getLength(); j++) < Node selement = slist.item(j); if (selement.getNodeType() == Node.ELEMENT_NODE) < String textval = selement.getTextContent(); if (selement.getNodeName().equals("FirstName")) < obj.setFirstname(textval); >if (selement.getNodeName().equals("LastName")) < obj.setLastname(textval); >> > students.add(obj); > 
public class Student < private String id; private String firstname; private String lastname; private Address adr; private ArrayListcourses; 

1 Answer 1

So, one way to approach this is to create Data structures for both Address and Class, like so:

and (note: calling a Java Class "Class" may prove to be very confusing, so use something else I'd say)

(and you'll have to create constructors for both of those classes too)

Then, in your for-loop, in the outer "if" block, after the "if" statements that check the node names for "FirstName" and "LastName", you could do something like:

if (selement.getNodeName().equals("Address")) < String street = null; String city = null; String state = null; String zip = null; String phone = null; NodeList addressChildren = selement.getChildNodes(); for(int k=0; k < addressChildren.getLength(); k++) < Node addrNode = addressChildren.item(k); if(addrNode.getNodeName().equals("Street") < street = addrNode.getTextContent(); >. //etc for City, State, Zip, and Phone Address a = new Address(street, city, state, zip, phone) obj.setAddress(a); > > if (selement.getNodeName().equals("Classes")) < NodeList classNodes = selement.getChildNodes(); Course[] courses = new Course[classNodes.getLength()); for(int l=0; l < classNodes.getLength(); l++) < Node classNode = classNodes.item(l); NodeList classChildren = classNode.getChildNodes(); for(int m=0; m < classChildren.getLenght(); m++) < Node classChild = classChildren.item(i); int crn = Integer.parseInt(classChild.getAttributes().getNamedItem("crn").getTextContent()); String name = null; String units = null; if(classChild.getNodeName().equals("Name") < name = classChild.getTextContent(); >if(classChild.getNodeName().equals("Units") < units = classChild.getTextContent(); >courses[m] = new Course(crn, name, units); > obj.setCourses(Arrays.asList(courses)); > > 

Ok, so the code above isn't perfect (I wrote it in the browser), but I think, based on what you've already figured out about XML parsing, that this is a good start.

Источник

Java: Having trouble parsing XML with nested nodes

I understand there are different ways to parse XML, I was wondering if I should stick to the method I'm using and build off of it, or should I try a different, easier approach. Also wondering if I could get a pointer with parsing the rest of the album information if possible

If you're not just doing this as a learning exercise, then it's worth nothing that XStream is your friend. There's also JAXB.

If you want to parse whole xml of this small length, I can provide you working code of recursive DOM parser which will parse all data value of your xml without having knowledge of any tag. DOM can be used for such small xml where your requirement is to parse whole xml.

3 Answers 3

The short answer is, yes, you should drop your current approach and seek something else. Many hundreds of developer hours have gone into producing libraries that are capable of parsing XML files in standardised manner.

There are any number of libraries available for parsing XML.

You could start by taking a look at the inbuilt APIs, Java API for XML Processing (JAXP).

Generally it comes down to two approaches.

SAX is basically inline processing of the XML as it's parsed. This means, that as the XML document is being processed, you are been given the opportunity to process that parsing. This is good for large documents and when you only need linear access to the content.

DOM (or Document Object Model) generates a model of the XML, which you can process at your leisure. It's better suited to smaller XML documents, as the entire model is normally read into memory and when you want to interact with the document in a non-linear fashion, such as searching for example.

The following is a simple snippet of loading a XML document in a DOM.

try < DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); try < Document doc = builder.parse(new File("Album.xml")); >catch (SAXException | IOException ex) < ex.printStackTrace(); >> catch (ParserConfigurationException exp)

Once you have the Document , you are ready to process it in any way you see fit. To my mind, it'd take a look at XPath, which is a query API for XML

import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class SongList < public static void main(String[] args) < try < DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); try < Document doc = builder.parse(new File("Album.xml")); XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); // Find all album tabs starting at the root level XPathExpression xExpress = xPath.compile("/album"); NodeList nl = (NodeList)xExpress.evaluate(doc.getDocumentElement(), XPathConstants.NODESET); for (int index = 0; index < nl.getLength(); index++) < Node albumNode = nl.item(index); // Find the title node that is a child of the albumNode Node titleNode = (Node) xPath.compile("title").evaluate(albumNode, XPathConstants.NODE); System.out.println(titleNode.getTextContent()); >// Find all albums whose title is equal to " Sample Album " xExpress = xPath.compile("/album[title=' Sample Album ']"); nl = (NodeList)xExpress.evaluate(doc.getDocumentElement(), XPathConstants.NODESET); for (int index = 0; index < nl.getLength(); index++) < Node albumNode = nl.item(index); Node titleNode = (Node) xPath.compile("title").evaluate(albumNode, XPathConstants.NODE); System.out.println(titleNode.getTextContent()); >> catch (SAXException | IOException | XPathExpressionException ex) < ex.printStackTrace(); >> catch (ParserConfigurationException exp) < exp.printStackTrace(); >> > 

Источник

Читайте также:  Питон перевернуть двоичное число
Оцените статью