如何通过stAX或SAX从xml字符串中获取特定的事件/属性内容

时间:2012-10-04 12:07:18

标签: java xml parsing sax stax

我有一个xml POST响应,我收到它作为字符串。我需要特定“pnr”的内容(参见xml)将其传递给另一个GET请求。 我正在尝试使用sax和stAX来实现这一目标但却失败了。 我使用了getElementsByTagName和getAttribute,但没有去... 这是我的代码,后来是我收到的xml字符串。

任何形式的帮助都将成为礼物

package rest;
import javax.xml.parsers.*;
import org.xml.sax.InputSource;
import org.w3c.dom.*;
import java.io.*;


public class ParseXMLString {

  public static void main(String arg[]) {
    String outputString =  RESTClient.postConfirm(); // this is the xml string response I am getting

    try {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        InputSource is = new InputSource();
        is.setCharacterStream(new StringReader(outputString));

        Document doc = db.parse(is);
        String Parentnode = doc.getDocumentElement().getAttribute("pnr");       
//           Element element = (Element) Parentnode.;
//           NodeList name = element.getElementsByTagName("pnr");
//           Element line = (Element) name.item(0);
           //String IDList = getCharacterDataFromElement(line);   
           System.out.println(Parentnode);
    }
    catch (Exception e) {
        e.printStackTrace();
    }
  }

  public static String getCharacterDataFromElement(Element e) {
    Node child = e.getFirstChild();
    if (child instanceof CharacterData) {
       CharacterData cd = (CharacterData) child;
       return cd.getData();
    }
    return "?";
  }
}

这是我收到的XML字符串:

<?xml version="1.0" encoding="UTF-8"?><Ticket><bookedSeats>3</bookedSeats><bpAddress>Anand Rao Circle</bpAddress><bpLandMark>ganesha temple</bpLandMark><bpLocation> Ghousia College</bpLocation><bpPhoneNo>98798679769</bpPhoneNo><bpTime>1200</bpTime><busServiceName>efdf</busServiceName><busType>Volvo A/C Semi Sleeper (2+2)</busType><commission>66.19</commission><dateOfJourney>2012-10-05</dateOfJourney><destination>Chennai</destination><fare>600.0</fare><issueTime>2012-10-04T15:46:45.073+05:30</issueTime><noOfSeats>1</noOfSeats><passengerMobile>1234567890</passengerMobile><passengerName>Test</passengerName><pnr>RATPKES44974756</pnr><seatDetails><seatDetail><commission>66.19</commission><fare>600.0</fare><gender>MALE</gender><passengerAge>0</passengerAge><passengerMobile>1234567890</passengerMobile><passengerName>Test</passengerName><prime>false</prime><seatName>3</seatName></seatDetail></seatDetails><source>Bangalore</source><status>BOOKED</status><travelsName>Rajratan Travels</travelsName></Ticket>

3 个答案:

答案 0 :(得分:0)

这段代码将为您提供pnr:

                 NodeList nodeLst = doc.getElementsByTagName("Ticket");
                 Node ticket = nodeLst.item(0);
                 NodeList attr = ticket.getChildNodes();
                 for (int i = 0; i < attr.getLength(); i++){
                     if (attr.item(i).getNodeName().equals("pnr"))
                         System.out.println(attr.item(i).getTextContent());
                 }

答案 1 :(得分:0)

如果我要解决这个问题,我可能会使用XPath。但是既然你特意要求StAX,这里有一个示例解析器(请注意,这只是骨架代码,可以帮助您入门)。

import java.io.StringReader;
import java.util.Iterator;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public class ParseXMLStringStAX {

    private static final String PNR = "pnr";

    private String characters;

    public String parse(String xmlString) throws XMLStreamException, Exception {
        XMLEventReader reader = null;
        try {
            if (xmlString == null || xmlString.isEmpty()) {
                throw new IllegalArgumentException("Illegal initializiation (xmlString is null or empty)");
            }
            StringReader stringReader = new StringReader(xmlString);
            XMLInputFactory inputFact = XMLInputFactory.newInstance();
            XMLStreamReader streamReader = inputFact.createXMLStreamReader(stringReader);
            reader = inputFact.createXMLEventReader(streamReader);

            while (reader.hasNext()) {
                XMLEvent event = reader.nextEvent();

                if (event.isCharacters()) {
                    characters(event);
                }
                if (event.isStartElement()) {
                    startElement(event);
                    // handle attributes
                    Iterator<Attribute> attributes = event.asStartElement().getAttributes();
                    while(attributes.hasNext()) {
                        attribute(attributes.next());
                    }
                }
                if (event.isEndElement()) {
                    // found what we want?
                    if (endElement(event)) {
                        endDocument(null);
                        break;
                    }
                }
                if (event.isStartDocument()) {
                    startDocument(event);
                }
                if (event.isEndDocument()) {
                    endDocument(event);
                }

            }
        } catch (XMLStreamException ex) {
            throw ex;
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (XMLStreamException ex) {
            }
        }
        return characters;
    }

    private void attribute(XMLEvent event) throws Exception {

    }

    private void characters(XMLEvent event) throws Exception {
        Characters asCharacters = event.asCharacters();
        if (asCharacters.isWhiteSpace())
            return;
        if (characters == null) {
            characters = asCharacters.getData();
        } else {
            characters += asCharacters.getData();
        }
    }

    private void startElement(XMLEvent event) throws Exception {
        StartElement startElement = event.asStartElement();
        String name = startElement.getName().getLocalPart();
        characters = null;
    }

    private boolean endElement(XMLEvent event) throws Exception {
        EndElement endElement = event.asEndElement();
        String name = endElement.getName().getLocalPart();
        if (PNR.equals(name)) {
            return true;
        }
        return false;
    }

    private void startDocument(XMLEvent event) {
        System.out.println("Parsing started");
    }

    private void endDocument(XMLEvent event) {
        System.out.println("Parsing ended");
    }

    public static void main(String[] argv) throws XMLStreamException, Exception {
        String xml = "";

        xml += "<Ticket>";
        xml += "    <bookedSeats>3</bookedSeats>";
        xml += "    <bpAddress>Anand Rao Circle</bpAddress>";
        xml += "    <bpLandMark>ganesha temple</bpLandMark>";
        xml += "    <bpLocation> Ghousia College</bpLocation>";
        xml += "    <bpPhoneNo>98798679769</bpPhoneNo>";
        xml += "    <bpTime>1200</bpTime>";
        xml += "    <busServiceName>efdf</busServiceName>";
        xml += "    <busType>Volvo A/C Semi Sleeper (2+2)</busType>";
        xml += "    <commission>66.19</commission>";
        xml += "    <dateOfJourney>2012-10-05</dateOfJourney>";
        xml += "    <destination>Chennai</destination>";
        xml += "    <fare>600.0</fare>";
        xml += "    <issueTime>2012-10-04T15:46:45.073+05:30</issueTime>";
        xml += "    <noOfSeats>1</noOfSeats>";
        xml += "    <passengerMobile>1234567890</passengerMobile>";
        xml += "    <passengerName>Test</passengerName>";
        xml += "    <pnr>RATPKES44974756</pnr>";
        xml += "    <seatDetails>";
        xml += "        <seatDetail>";
        xml += "            <commission>66.19</commission>";
        xml += "            <fare>600.0</fare>";
        xml += "            <gender>MALE</gender>";
        xml += "            <passengerAge>0</passengerAge>";
        xml += "            <passengerMobile>1234567890</passengerMobile>";
        xml += "            <passengerName>Test</passengerName>";
        xml += "            <prime>false</prime>";
        xml += "            <seatName>3</seatName>";
        xml += "        </seatDetail>";
        xml += "    </seatDetails>";
        xml += "    <source>Bangalore</source>";
        xml += "    <status>BOOKED</status>";
        xml += "    <travelsName>Rajratan Travels</travelsName>";
        xml += "</Ticket>";

        ParseXMLStringStAX parser = new ParseXMLStringStAX();
        String pnr = parser.parse(xml);
        System.out.println("--> Result: " + String.valueOf(pnr));
    }
}

答案 2 :(得分:0)

自Java SE 5起,您可以使用JDK / JRE中的javax.xml.xpath API执行以下操作,而不是SAX或StAX:

<强>演示

import java.io.StringReader;
import javax.xml.xpath.*;
import org.xml.sax.InputSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        String xml = "<?xml version='1.0' encoding='UTF-8'?><Ticket><bookedSeats>3</bookedSeats><bpAddress>Anand Rao Circle</bpAddress><bpLandMark>ganesha temple</bpLandMark><bpLocation> Ghousia College</bpLocation><bpPhoneNo>98798679769</bpPhoneNo><bpTime>1200</bpTime><busServiceName>efdf</busServiceName><busType>Volvo A/C Semi Sleeper (2+2)</busType><commission>66.19</commission><dateOfJourney>2012-10-05</dateOfJourney><destination>Chennai</destination><fare>600.0</fare><issueTime>2012-10-04T15:46:45.073+05:30</issueTime><noOfSeats>1</noOfSeats><passengerMobile>1234567890</passengerMobile><passengerName>Test</passengerName><pnr>RATPKES44974756</pnr><seatDetails><seatDetail><commission>66.19</commission><fare>600.0</fare><gender>MALE</gender><passengerAge>0</passengerAge><passengerMobile>1234567890</passengerMobile><passengerName>Test</passengerName><prime>false</prime><seatName>3</seatName></seatDetail></seatDetails><source>Bangalore</source><status>BOOKED</status><travelsName>Rajratan Travels</travelsName></Ticket>";

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

        InputSource inputSource = new InputSource(new StringReader(xml));
        String pnr = (String) xpath.evaluate("/Ticket/pnr", inputSource, XPathConstants.STRING);
        System.out.println(pnr);
    }

}

<强>输出

RATPKES44974756