This week's book giveaway is in the OCP forum.
We're giving away four copies of OCP Java SE 8 Programmer II Exam Study Guide and have Kathy Sierra, Bert Bates, & Elizabeth Robson on-line!
See this thread for details.
Win a copy of OCP Java SE 8 Programmer II Exam Study Guide this week in the OCP forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Reading xml file getting stuck on some tags  RSS feed

 
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all, i am trying to read an xml file but I am getting stuck with some tags...i have tried many different things but cannot seem to figure out how to get some tags.
Any help would be greatly appreciated.
The tags that I am not able to get are queted with "HELP"


XML File:



This is my code to get the data:
 
Sheriff
Posts: 23451
46
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, let's see. All of your element nodes are in a namespace; the namespace prefix is "cfdi" but its namespace URI is declared here:



That's kind of strange, it looks like somebody's modified the root element by removing all of the namespace URIs, which is going to confuse the issue.

Then I'm confused, because you're using a Document object which has a getRootElement() method. I was assuming that was the Document object from the standard Java API, namely org.w3c.dom.Document, but it doesn't have that method. So you need to show us your imports so we know where that Document class came from.
 
Eduardo Ponce de Leon
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul, thank you very much for the reply.

This is the complete file with nothing removed, the only reason I did that was to make it more easy to read



and this is my complete code



So I need to get both values for this specific file inside "cfdi:Traslados" and there can be from 1 to n

 
Paul Clapham
Sheriff
Posts: 23451
46
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


It's like I guessed originally: your XML elements have namespaces but you're not writing the correct code for a document with namespaces. You need to use the getElementsByTagNameNS(namespaceURI, localName) method.

In the line of code I copied, the namespaceURI is the URI of the namespace whose prefix in this document is "cfdi". That namespace is declared in the document element, I'm not going to try to copy it here. And the localName is simply "Emisor".
 
Eduardo Ponce de Leon
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul, thank you but i am unsure why do I need to use the emisor tag if I have no problem getting the information inside that tag.

My problem is getting the information inside the tag below, which i need to get "Importe" and "TasaOCuota"
 
Paul Clapham
Sheriff
Posts: 23451
46
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I suppose that when you're talking about "tags" you mean XML elements. Anyway if you have no problem getting information inside an element, then you should have no problem in getting an attribute from that element. And you already have code which uses the getAttribute() method of an element. So I don't understand your problem.
 
Eduardo Ponce de Leon
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
if i am posting it is because i cant get inside that specific xml element, otherwise i wouldnt be here asking for help.
 
Paul Clapham
Sheriff
Posts: 23451
46
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So does that mean you can't find the element? Because if you could, then you could get one of its attributes.
 
Ranch Hand
Posts: 706
3
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

    nodeLst = doc.getElementsByTagName("cfdi:Traslado");

    for (int s = 0; s < nodeLst.getLength(); s++) {
      if (s == nodeLst.getLength() - 1) {
        Node fstNode = nodeLst.item(s);

        if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
          Element fstElmnt = (Element) fstNode;
          if (doc.getElementsByTagName("cfdi:Traslado") != null) {
            System.out.println(fstElmnt.hasChildNodes());
            System.out.println(fstElmnt.getAttribute("Importe") + "|"
                + fstElmnt.getAttribute("TasaOCuota") + "|"
                + fstElmnt.getAttribute("Impuesto"));
          }
        }
      }
    }


Look at this block of code where you want to find the data you said you want.

[1]

if (s == nodeLst.getLength() - 1) {
   // etc etc
}


That mean you don't want to get all but you want to get only the last element cfdi:Traslado. That is a contradition. Take the test out.

[2]

if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
    //etc etc
}


This test is absolutely unnecessary. getElementsByTagName is getting "element", nothing else. The resultant node list contains only node, if any, of type Node.ELEMENT_NODE.  The conditional is alway true. Take out the if statement and keep the content. And that means also the casting (Element) will not pose any problem at all.

[3]

if (doc.getElementsByTagName("cfdi:Traslado") != null) {
    //etc etc
}


Again, this is absolutely unnecessay. You must get something already to get to that stage. Beside, even if getElementsByTagName gets nothing, it will return all the same a NodeList, only that it is empty, that's all. The return is not null in any case. So again take out the if statement and keep the content.

[4] Now the part of namespace mentioned several times already. This is the point: if you use getElementsByTagName() with tag name prefixed, hence containing a characteristic colon (:), that prefix must _exactly_ match what is used in the xml doc, hence, you make a rigidity out of non-generic and flexible part of the specificiation. You can do it once for a while, but that code would not be robust. As far as you code is concerned, you can keep it this time and get the results until further revision.

[4.1] But if you want to use the more proper approach as mentioned a couple of time, the line would look like this.

But... You cannot simple do this. You have to make the builder factory namespace aware beforehand in order to use it, otherwise, it won't do. That means you have to do this as well.

And then it is good to use the namespace aware version of getElementsByTagName(), that is getElementsByTagNameNS() method.

That is all you need to do.
 
Eduardo Ponce de Leon
Ranch Hand
Posts: 107
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This was really helpful unlike other posts.
 
Paul Clapham
Sheriff
Posts: 23451
46
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, g tsuji took the time to go through your code, which I didn't. Sorry about that.
 
Eduardo Ponce de Leon
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:Yes, g tsuji took the time to go through your code, which I didn't. Sorry about that.



Either way, thank you for the help.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!