2

my question is "DOM parser, why do I get just one child of an element?"

I looked into this and this one, but I do not get the point.

What I'm trying to do is the following:

I have an XML file (see the extract below) :

<POITEM>
   <item>
      <PO_ITEM>00010</PO_ITEM>
      <SHORT_TEXT>ITEM_A</SHORT_TEXT>
      <MATL_GROUP>20010102</MATL_GROUP>
      <AGREEMENT>4600010076</AGREEMENT>
      <AGMT_ITEM>00010</AGMT_ITEM>
      <HL_ITEM>00000</HL_ITEM>
      <NET_PRICE>1.000000000</NET_PRICE>
      <QUANTITY>1.000</QUANTITY>
      <PO_UNIT>EA</PO_UNIT>
   </item>
   <item>
      <PO_ITEM>00020</PO_ITEM>
      <SHORT_TEXT>ITEM_B</SHORT_TEXT>
      <MATL_GROUP>20010102</MATL_GROUP>
      <AGREEMENT>4600010080</AGREEMENT>
      <AGMT_ITEM>00020</AGMT_ITEM>
      <HL_ITEM>00000</HL_ITEM
      <NET_PRICE>5.000000000</NET_PRICE>
      <QUANTITY>5.000</QUANTITY>
      <PO_UNIT>EA</PO_UNIT>
   </item>
</POITEM>

I only want to extract <PO_ITEM>, <SHORT_TEXT>, <MATL_GROUP>, <NET_PRICE>, <QUANTITY> and <PO_UNIT> and write it into another, smaller XML file.

So this is my code:

nodes = dcmt.getElementsByTagName("POITEM");

Element rootElement2 = doc1.createElement("PO_POSITIONS");
rootElement1.appendChild(rootElement2);

Element details2 = doc1.createElement("PO_DETAILS");
rootElement2.appendChild(details2);

for (int i = 0; i < nodes.getLength(); i++) {
    Node node = nodes.item(i);
    if (node.getNodeType() == Node.ELEMENT_NODE) {
        Element element = (Element) node;

        Element position = doc1.createElement("position");
        details2.appendChild(position);

        Element poItm = doc1.createElement("PO_ITEM");
        poItm.appendChild(doc1.createTextNode(getValue("PO_ITEM", element)));
        position.appendChild(poItm);

        Element matlGrp = doc1.createElement("MATL_GROUP");
        matlGrp.appendChild(doc1.createTextNode(getValue("MATL_GROUP",element)));
        position.appendChild(matlGrp);

        Element poUnit = doc1.createElement("PO_UNIT");
        poUnit.appendChild(doc1.createTextNode(getValue("PO_UNIT",element)));
        position.appendChild(poUnit);

        Element netPrice = doc1.createElement("NET_PRICE");
        netPrice.appendChild(doc1.createTextNode(getValue("NET_PRICE",element)));
        position.appendChild(netPrice);

        Element shortTxt = doc1.createElement("SHORT_TEXT");
        shortTxt.appendChild(doc1.createTextNode(getValue("SHORT_TEXT",element)));
        position.appendChild(shortTxt);

        //Element matl = doc2.createElement("MATERIAL");
        //matl.appendChild(doc2.createTextNode(getValue("MATERIAL",element)));
        //details2.appendChild(matl);

        Element qnty = doc1.createElement("QUANTITY");
        qnty.appendChild(doc1.createTextNode(getValue("QUANTITY",element)));
        position.appendChild(qnty);

        /*Element preqNr = doc1.createElement("PREQ_NO");
          preqNr.appendChild(doc1.createTextNode(getValue("PREQ_NO",element)));
          details2.appendChild(preqNr); */
    }
}

So far so good, I'm getting a new XML File, but it only holds the first entry, so as i understand it, by the nodes = dcmt.getElementsByTagName("POITEM"); gets into the first <item> until the first </item> and then gets out of the loop. So how do I manage step into the next item? Do I need to create some kind of loop, to access the next <item> ? By the way, changing the structure of the XML file is no option, since I get the file from an interface. Or do I make a mistake while writing the new XML file?

The output looks like this:

<PO_POSITIONS>
  <PO_DETAILS>
    <position>
      <PO_ITEM>00010</PO_ITEM>
      <MATL_GROUP>20010102</MATL_GROUP>
      <PO_UNIT>EA</PO_UNIT>
      <NET_PRICE>1.00000000</NET_PRICE>
      <SHORT_TEXT>ITEM_A</SHORT_TEXT>
      <QUANTITY>1.000</QUANTITY>
    </position>
  </PO_DETAILS>
</PO_POSITIONS>
Community
  • 1
  • 1
print x div 0
  • 1,474
  • 1
  • 15
  • 33
  • Since your XML and the code don't match, it is difficult to figure out what is going on. – Stephen C Jul 31 '13 at 09:25
  • @Stephen C Okay, Why? My problem is, that I only get back the attributes of the first ``. I see the problem in the **nodes = dcmt.getElementsByTagName("POITEM")** part. And I get a XML file out of it, which contains the first ``, but not the second, third an so on. – print x div 0 Jul 31 '13 at 09:32
  • You don't get it. The XML doesn't contain an element called "POITEM" ... so the program cannot possibly behave as you describe. Please provide a *proper* SSCCE and *proper* input, not some bowdlerised hacked-around stuff that doesn't make sense. We can't read your mind. – Stephen C Jul 31 '13 at 09:36
  • Oh, sorry. i see my mistake now. okay, I will provide an extract from the actual XML File. – print x div 0 Jul 31 '13 at 09:39

1 Answers1

1

You could parse it yourself, it's kind of a pain. When I did xml way back when, we used to use stylesheets to do these kinds of transformations. Something like this post: How to transform XML with XSL using Java

If that's not an option, then to do it by hand (I omitted the new document construction, but you can see where it goes):

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XMLTest { 
    @Test
    public void testXmlParsing() throws Exception {
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(new File("/Users/aakture/Documents/workspace-sts-2.9.1.RELEASE/smartfox/branches/trunk/java/gelato/src/test/resources/sample.xml").getAbsolutePath());
        Node poItem = doc.getElementsByTagName("POITEM").item(0);
        NodeList poItemChildren = poItem.getChildNodes();
        for (int i = 0; i < poItemChildren.getLength(); i++) {
            Node item = poItemChildren.item(i);
            NodeList itemChildren = item.getChildNodes();
            for (int j = 0; j < itemChildren.getLength(); j++) {
                Node itemChild = itemChildren.item(j);
                if("PO_ITEM".equals(itemChild.getNodeName())) {
                    System.out.println("found PO_ITEM: " +     itemChild.getTextContent());
                }
                if("MATL_GROUP".equals(itemChild.getNodeName())) {
                    System.out.println("found MATL_GROUP: " + itemChild.getTextContent());
                }

            }
        }
    }
}
Community
  • 1
  • 1
Alper Akture
  • 2,445
  • 1
  • 30
  • 44