2

我正在尝试将 XML 字符串从服务器传递到解析器并制作对象数组列表,但我目前得到的只是一个空数组列表。

获取和解析 XML 的代码

package parkinglot_api;

import java.net.*;
import java.sql.Date; 
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.io.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class ParkingLotInstance {
/*
 * Parking Lot API instance
 *      Constructor
 *          URL - String
 *      getParkingLotInfo()
 *          Returns XML from Specified Server
 *      parseParkingLotInfo()
 *          XML - String
 *          Returns ArrayList of Lot Objects
 */

public static URL serverURL;

public ParkingLotInstance( URL connurl ){
    serverURL = connurl;
}

public String getParkingLotInfo(){
    //Get a response from API server

    URL APIurl = this.serverURL;
    String APIresponse = "";

    System.out.println(APIurl);
    try {
        APIurl.openConnection();
        BufferedReader in = new BufferedReader(
                new InputStreamReader(APIurl.openStream()));

        String output;
        while ((output = in.readLine()) != null)
            APIresponse += output;
        in.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return APIresponse;

}

public ArrayList parseParkingLotInfo( String XML ){
        ArrayList lots = new ArrayList();

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        try {

            //Using factory get an instance of document builder

             dbf.setNamespaceAware(false);
             DocumentBuilder builder = dbf.newDocumentBuilder();

             InputSource inStream = new InputSource();

             inStream.setCharacterStream(new StringReader(XML));
             Document dom = builder.parse(inStream);


            //get the root element
            Element docEle = dom.getDocumentElement();

            //get a nodelist of elements
            NodeList nl = docEle.getElementsByTagName("Lot");

            if(nl != null && nl.getLength() > 0) {
                for(int i = 0 ; i < nl.getLength();i++) {

                    //get the employee element
                    Element el = (Element)nl.item(i);

                    //get the Employee object
                    Lot l = parseLot(el);

                    //add it to list
                    lots.add(l);
                }
            }


        }catch(ParserConfigurationException pce) {
            pce.printStackTrace();
        }catch(SAXException se) {
            se.printStackTrace();
        }catch(IOException ioe) {
            ioe.printStackTrace();
        }


        return lots;
}

public Lot parseLot(Element el){

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");

    //Initialize Parking Lot Variables
    int id = getIntValue(el,"id");
    int occupancy = getIntValue(el,"occupancy");
    Boolean status = Boolean.parseBoolean(getTextValue(el,"status"));
    String name = getTextValue(el,"name");
    Date updated = null;
    try {
        updated = (Date) dateFormat.parse(getTextValue(el,"updated"));
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
    String description = getTextValue(el,"description");

    //Construct Parking Lot
    Lot lot = new Lot( 
         id
       , occupancy 
       , status
       , name
       , updated
       , description 
      );

    return lot;
}

/**
 * I take a xml element and the tag name, look for the tag and get
 * the text content
 * i.e for <employee><name>John</name></employee> xml snippet if
 * the Element points to employee node and tagName is 'name' I will return John
 */
private String getTextValue(Element ele, String tagName) {
    String textVal = null;
    NodeList nl = ele.getElementsByTagName(tagName);
    if(nl != null && nl.getLength() > 0) {
        Element el = (Element)nl.item(0);
        textVal = el.getFirstChild().getNodeValue();
    }

    return textVal;
}


/**
 * Calls getTextValue and returns a int value
 */
private int getIntValue(Element ele, String tagName) {
    //in production application you would catch the exception
    return Integer.parseInt(getTextValue(ele,tagName));
}
}

对象类

 package parkinglot_api;

 import java.util.Date;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.io.xml.DomDriver;

 public class Lot {
/*
 * Parking Lot Object
 *     ID: Unique Identifier
 *     Occupancy: The Current Amount of Cars in the Lot
 *     Status: Describes if the Lot is Open or Closed
 *     Name: A String Identifier of the Lot
 *     Updated: The Last time the Lot's current status record was updated.
 */

//Initiate Parking Lot Fields
public int id;
public int occupancy;
public Boolean status;
public String description;
public String name;
public Date updated;

//Parking Lot Constructor
public Lot( 
      int newId
    , int newOccupancy 
    , Boolean newStatus
    , String newName
    , Date newUpdated
    , String newDescription 
){

    id = newId;
    occupancy = newOccupancy;
    status = newStatus;
    name = newName;
    updated = newUpdated;
    description = newDescription;
}

//Convert Java Object to JSON
public String toJSON(){
    Gson gson = new GsonBuilder().setPrettyPrinting().create();

    String jsonLot = gson.toJson(this);
    return jsonLot;
}

//Convert Java Object to XML
public String toXML(){
    XStream xstream = new XStream(new DomDriver());
    xstream.alias("lot", Lot.class);
    String xml = xstream.toXML(this);

    return xml;
}
}

从实例类调用方法的类

 package parkinglot_api;

 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;


 public class Example {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    URL serverURL;
    try {
        serverURL = new URL("http://localhost:8080");

        ParkingLotInstance API = new ParkingLotInstance(serverURL);

        String parkingLotXML = API.getParkingLotInfo();

        ArrayList Lots = API.parseParkingLotInfo(parkingLotXML);

        System.out.println(Lots);

    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

 }

XML

<?xml version='1.0' ?>
    <campus count='4'>
    <lot>
      <id>1</id>
      <occupancy>25</occupancy>
      <status>true</status>
      <description></description>
      <name>lot1</name>
      <updated class="sql-date">2012-10-05</updated>
    </lot>
    <lot>
      <id>2</id>
      <occupancy>25</occupancy>
      <status>true</status>
      <description></description>
      <name>lot2</name>
      <updated class="sql-date">2012-10-06</updated>
    </lot>
    <lot>
      <id>3</id>
      <occupancy>25</occupancy>
      <status>false</status>
      <description></description>
      <name>lot3</name>
      <updated class="sql-date">2012-10-07</updated>
    </lot>
    <lot>
      <id>4</id>
      <occupancy>25</occupancy>
      <status>true</status>
      <description></description>
      <name>lot4</name>
      <updated class="sql-date">2012-11-07</updated>
    </lot>
    </campus>
4

3 回答 3

2

我认为最好的解决方案是使用为您完成所有工作的 JAXB。你可以在这里找到一个很好的教程

于 2012-05-08T21:37:29.760 回答
1

getElementsByTagName("...")区分大小写,您"lot"的文件和docEle.getElementsByTagName("Lot")代码中都有,请尝试将其替换为docEle.getElementsByTagName("lot")

于 2012-05-08T21:44:11.447 回答
0

是的,您应该使用带有适当注释的 JAXB。通过这种方式,您可以避免大部分解析内容逻辑。Jaxb 会为你做这件事。

于 2014-11-11T07:19:36.243 回答