2

I receive XML String from Client as

<?xml version="1.0" encoding="UTF-8"?>
<Esp:Interface Version="1.0" xmlns:Esp="http://***Confidential****/">
<Esp:Transaction ActionCode="APPROVE" CardNumber="474849********28" ExpiryDate="0824" 
    ResponseCode="00" TerminalId="03563001" Track2="474849********28=08241261234" 
    TransactionAmount="300" TransactionId="00051" Type="PURCHASE" LocalDate="0823" 
    LocalTime="152006" PosOperatorId="1234" AuthorizationNumber="123456" MessageType="REFERAL">
</Esp:Transaction>
</Esp:Interface>

I want to extract each string like

ActionCode="APPROVE" 
CardNumber="474849********28" 
ExpiryDate="0824" 
ResponseCode="00" 
TerminalId="03563001" 
Track2="474849********28=08241261234" 
TransactionAmount="300" 
TransactionId="00051" 
Type="PURCHASE" 
LocalDate="0823" 
LocalTime="152006" 
PosOperatorId="1234" 
AuthorizationNumber="123456" 
MessageType="REFERAL"

I used XPath to read XML String but it gives me error

InputSource source = new InputSource(new StringReader(sXMLData));//sXMLData Contains XML String     

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(source);

XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();

String msg = xpath.evaluate("/Esp:Interface/Esp:Transaction", document);

System.out.println("msg= " + msg);

Error :

msg : /* Coming Blank */

I referred these two links but didnt get help as much Parse XML Simple String using Java XPath And Simplest way to query XML in Java

How can i get these individual strings from XML ... by using build in XML or old substring method (inefficient)

Community
  • 1
  • 1
Shaggy
  • 5,422
  • 28
  • 98
  • 163

2 Answers2

2

Your XPath is wrong. You're asking XPath for the content of the element, which is indeed empty. In order to get the attributes, you'll need to either get them individually:

/Esp:Interface/Esp:Transaction/@ActionCode

Or you can get them all at once

/Esp:Interface/Esp:Transaction/@*

But this will give you a group of Nodes from the document, each of which will have a name and a value, which you'll have to pull out in your code. There's no way that I know of to just get the string of attributes as it appears in the document.

Ian McLaird
  • 5,507
  • 2
  • 22
  • 31
1

That sounds like you have some forbidden characters before the <?xml ...?>. Make sure the file is correctly saved as UTF-8 and no whitespace is before the declaration.

To parse the attributes, in this simple case, I'd recommend a SAX parser:

public class MySaxHandler extends DefaultHandler {
    public static void main(String[] args) throws Throwable {
        String sXMLData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
                + "<Esp:Interface Version=\"1.0\" xmlns:Esp=\"http://***Confidential****/\">\r\n"
                + "<Esp:Transaction ActionCode=\"APPROVE\" CardNumber=\"474849********28\" ExpiryDate=\"0824\" \r\n"
                + "    ResponseCode=\"00\" TerminalId=\"03563001\" Track2=\"474849********28=08241261234\" \r\n"
                + "    TransactionAmount=\"300\" TransactionId=\"00051\" Type=\"PURCHASE\" LocalDate=\"0823\" \r\n"
                + "    LocalTime=\"152006\" PosOperatorId=\"1234\" AuthorizationNumber=\"123456\" MessageType=\"REFERAL\">\r\n"
                + "</Esp:Transaction>\r\n" + "</Esp:Interface>";
        InputSource source = new InputSource(new StringReader(sXMLData));
        XMLReader reader = XMLReaderFactory.createXMLReader();
        reader.setContentHandler(new MySaxHandler());
        reader.parse(source);
    }

    @Override
    public void startElement(String uri, String localName, String qName,
              Attributes atts) throws SAXException {
        if (qName.equals("Esp:Transaction")) {
            for (int i = 0; i < atts.getLength(); i++) {
                System.out.println(atts.getQName(i) + "=\"" + atts.getValue(i) + "\"");
            }
        }
    }
}

Gives this output:

ActionCode="APPROVE"
CardNumber="474849********28"
ExpiryDate="0824"
ResponseCode="00"
TerminalId="03563001"
Track2="474849********28=08241261234"
TransactionAmount="300"
TransactionId="00051"
Type="PURCHASE"
LocalDate="0823"
LocalTime="152006"
PosOperatorId="1234"
AuthorizationNumber="123456"
MessageType="REFERAL"
Moritz Petersen
  • 12,902
  • 3
  • 38
  • 45
  • I can remove those characters..then what ? – Shaggy Aug 26 '13 at 12:55
  • How `startElement` method getting called ? actually i want to incorporate it into my project – Shaggy Aug 26 '13 at 13:51
  • That's the SAX parser API. Note this line: `reader.setContentHandler(new MySaxHandler());`. Here, the `ContentHandler` gets registered to the `XMLReader`. Then the method `parse()` is called, which internally invokes `startElement()` for each element. – Moritz Petersen Aug 26 '13 at 13:53
  • @MoritzPetersen I am passing `XMLData` to other class static method `public static void ParseXMLString(String sXMLData)` this class does not have `main` how this line will change `reader.setContentHandler(new MySaxHandler());` – Shaggy Aug 26 '13 at 14:01
  • My implementation is just one of many. This implementation doesn't need a `main` method. I don't know anything else about your code. It's now your task to solve this problem. Good luck! -- Hint: you need to implement a `ContentHandler` or extend a `DefaultHandler`, but this is not necessarily only one class. – Moritz Petersen Aug 26 '13 at 14:19