2013-04-14 2 views
3

DOM 파서를 사용하여 XML 파일을 구문 분석하려고합니다. XML 파일에는 이름, FAA 식별자, 위도/경도 및 URL별로 공항 목록이 포함되어 있습니다. 난 단지 이름으로 각 공항을 표시 할 수 있도록자바에서 DOM 파서로 객체를 만드시겠습니까?

<station> 
    <station_id>NFNA</station_id> 
    <state>FJ</state> 
    <station_name>Nausori</station_name> 
    <latitude>-18.05</latitude> 
    <longitude>178.567</longitude> 
    <html_url>http://weather.noaa.gov/weather/current/NFNA.html</html_url> 
    <rss_url>http://weather.gov/xml/current_obs/NFNA.rss</rss_url> 
    <xml_url>http://weather.gov/xml/current_obs/NFNA.xml</xml_url> 
</station> 

<station> 
    <station_id>KCEW</station_id> 
    <state>FL</state> 
      <station_name>Crestview, Sikes Airport</station_name> 
    <latitude>30.79</latitude> 
    <longitude>-86.52</longitude> 
      <html_url>http://weather.noaa.gov/weather/current/KCEW.html</html_url> 
      <rss_url>http://weather.gov/xml/current_obs/KCEW.rss</rss_url> 
      <xml_url>http://weather.gov/xml/current_obs/KCEW.xml</xml_url> 
</station> 

I 개체를 만들려고하고있다 (각 공항에 대한 하나) 각각의 정보를 포함, 공항 구문 분석 : 여기의 조각이다. 나머지 공항 정보는 나중에 프로젝트에서 사용됩니다.

누구나이 DOM 파서가 제공 한 정보에서 어떻게 개체를 만들고 인스턴스화하여 각 공항의 이름 만 표시 할 수 있는지 알려주실 수 있습니까?

import java.io.File; 

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

import org.w3c.dom.Document; 
import org.w3c.dom.Element; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 


public class Test { 

//initialize variables 
String station_id; 
String state; 
String station_name; 
double latitude; 
double longitude; 
String html_url; 

//Here is my constructor, I wish to instantiate these values with 
//those of obtained by the DOM parser 
Test(){ 

    station_id = this.station_id; 
    state = this.state; 
    station_name = this.station_name; 
    latitude = this.latitude; 
    longitude = this.longitude; 
    html_url = this.html_url; 

} 

//Method for DOM Parser 
    public void readXML(){ 

    try { 

     //new xml file and Read 
     File file1 = new File("src/flwxindex3.xml"); 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     Document doc = db.parse(file1); 
     doc.getDocumentElement().normalize(); 

     NodeList nodeList = doc.getElementsByTagName("station"); 

     for (int i = 0; i < nodeList.getLength(); i++) { 

      Node node = nodeList.item(i); 

      if(node.getNodeType() == Node.ELEMENT_NODE){ 

       Element first = (Element) node; 

       station_id =  first.getElementsByTagName("station_id").item(0).getTextContent(); 
       state = first.getElementsByTagName("state").item(0).getTextContent(); 
       station_name = first.getElementsByTagName("station_name").item(0).getTextContent(); 
       latitude = Double.parseDouble(first.getElementsByTagName("latitude").item(0).getTextContent()); 
       longitude = Double.parseDouble(first.getElementsByTagName("longitude").item(0).getTextContent()); 
       html_url = first.getElementsByTagName("station_id").item(0).getTextContent(); 
      } 

      /*These are just test to see if the actually worked 
      * 
      System.out.println(station_id); 
      System.out.println(state); 
      System.out.println(station_name); 
      System.out.println(latitude); 
      System.out.println(longitude); 
      System.out.println(html_url); 
      */ 

     } 
     } catch (Exception e) { 
     System.out.println("XML Pasing Excpetion = " + e); 
     } 

} 

public static void main(String[] args) { 

    //Create new object and call the DOM Parser method 
    Test test1 = new Test(); 
    test1.readXML(); 
    //System.out.println(test1.station_name); 


} 

} 

답변

3

당신은 당신의 클래스에 전역 변수를 가지고 :

여기 내 코드입니다. 당신은 당신의 변수를 포함하는 Object 필요합니다

public class Airport { 
    String stationId; 
    String state; 
    String stationName; 
    double latitude; 
    double longitude; 
    String url; 

    //getters/setters etc 
} 

지금 클래스 마지막으로

final List<Airport> airports = new LinkedList<Airport>(); 

만들고 루프

List에 공항의 인스턴스를 추가 상단에서 공항의 List를 만들
if(node.getNodeType() == Node.ELEMENT_NODE){ 

    final Element first = (Element) node; 
    final Airport airport = new Airport(); 

    airport.setStationId(first.getElementsByTagName("station_id").item(0).getTextContent()); 
    airport.setState(first.getElementsByTagName("state").item(0).getTextContent()); 
    //etc 
    airports.add(airport); 
} 

그리고 공항과 ​​쇼 이름을 반복하려면

for(final Airport airport : airports) { 
    System.out.println(airport.getStationName()); 
} 

솔직하게 말하면 조금 지저분합니다. XML을 Java POJO로 언 마샬하려는 경우 JAXB를 사용하는 것이 좋습니다.

다음은 XML 스키마, maven-jaxb2-plugin 및 JAXB를 사용한 빠른 예제입니다. 당신은 단지 다음 코드를 사용 Airport의 목록을 만들 수 있습니다 약간의 준비 (즉, 귀하의 XML 요소 이름으로 AirportStation이되었다)와

.

public static void main(String[] args) throws InterruptedException, JAXBException { 
    final JAXBContext jaxbc = JAXBContext.newInstance(Stations.class); 
    final Unmarshaller unmarshaller = jaxbc.createUnmarshaller(); 
    final Stations stations = (Stations) unmarshaller.unmarshal(Thread.currentThread().getContextClassLoader().getResource("airports.xml")); 
    for (final Station station : stations.getStation()) { 
     System.out.println(station.getStationName()); 
    } 
} 

출력 : 이것이 내가 XML 파일 형식

<xs:element name="stations"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element name="station" minOccurs="1" maxOccurs="unbounded"> 
       <xs:complexType> 
        <xs:all> 
         <xs:element name="station_id" type="xs:string"/> 
         <xs:element name="state" type="xs:string"/> 
         <xs:element name="station_name" type="xs:string"/> 
         <xs:element name="latitude" type="xs:decimal"/> 
         <xs:element name="longitude" type="xs:decimal"/> 
         <xs:element name="html_url" type="xs:anyURI"/> 
         <xs:element name="rss_url" type="xs:anyURI"/> 
         <xs:element name="xml_url" type="xs:anyURI"/> 
        </xs:all> 
       </xs:complexType> 
      </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
</xs:element> 

정의하는 XML 스키마를 만들어 작동하기 위해서는

Nausori 
Crestview, Sikes Airport 

가의 형식을 정의

귀하의 XML 파일. 두 개의 스테이션 태그를 래핑하는 stations 태그가 있습니다. 다음은 xml 예제입니다.

<stations> 
    <station> 
     <station_id>NFNA</station_id> 
     <state>FJ</state> 
     <station_name>Nausori</station_name> 
     <latitude>-18.05</latitude> 
     <longitude>178.567</longitude> 
     <html_url>http://weather.noaa.gov/weather/current/NFNA.html</html_url> 
     <rss_url>http://weather.gov/xml/current_obs/NFNA.rss</rss_url> 
     <xml_url>http://weather.gov/xml/current_obs/NFNA.xml</xml_url> 
    </station> 
    <station> 
     <station_id>KCEW</station_id> 
     <state>FL</state> 
     <station_name>Crestview, Sikes Airport</station_name> 
     <latitude>30.79</latitude> 
     <longitude>-86.52</longitude> 
     <html_url>http://weather.noaa.gov/weather/current/KCEW.html</html_url> 
     <rss_url>http://weather.gov/xml/current_obs/KCEW.rss</rss_url> 
     <xml_url>http://weather.gov/xml/current_obs/KCEW.xml</xml_url> 
    </station>  
</stations> 

내 pom.xml - maven 사용시 다음을 사용하여 스키마를 Java 클래스로 컴파일했습니다. Maven을 사용하지 않으면 커맨드 라인에서 xjc를 호출 할 수 있습니다.

<plugin> 
    <groupId>org.jvnet.jaxb2.maven2</groupId> 
    <artifactId>maven-jaxb2-plugin</artifactId> 
    <version>0.8.0</version> 
    <configuration> 
     <schemaDirectory>src/main/resources/</schemaDirectory> 
     <generatePackage>com.boris.airport</generatePackage>      
    </configuration> 
    <executions> 
     <execution> 
      <id>generate</id> 
      <goals> 
       <goal>generate</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 
+0

감사하지만 나는 더 많은 질문이 있습니다. DOM 내부에서 변수 (stationName 등)를 해결하는 데 문제가 있습니다. 나는 내가 새로운 공항 종류와 목록을 오해했다고 생각한다. 이 오류를 수정할 수 있도록 어디서 수정해야합니까? 나는 getters/setters도 만들었습니다. 어디서나 생성자가 필요합니까? 기본적으로 DOM은 더 이상 내 변수에 액세스 할 수 없습니다. – David

+0

DOM 내부에서 변수를 해결할 수 없습니다. 위 예제에서와 같이 getters/setters를 사용해야합니다. 'Object'는 명시 적으로 제공되지 않는 한 항상 [noargs 생성자] (http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html)를 가지고 있습니다. 아무 것도 필요하지 않으므로 생성자를 정의 할 필요가 없습니다. 이것은 [Java Bean] (http://en.wikipedia.org/wiki/JavaBeans)의 예입니다. –

+0

자바 메서드를 사용하여 각 필드의 별칭 이름을 설정할 수 없습니까? 또는 주석? –

0

당신은 역 속성을 저장하는 POJO 클래스를 사용할 수 있습니다.

이 프로그램은 BeanUtils을 사용하여 각 속성에 setter/getter를 사용하지 않고 bean에 속성을 채 웁니다.

는 당신의 XML에없는

한가지 더

<?xml version="1.0" encoding="UTF-8"?> 

및 묶으

루트 요소를 말한다 유효한 XML을 형성하기 위해 아래와 같이 외부 stations 태그의 모든 station입니다

<?xml version="1.0" encoding="UTF-8"?> 
<stations> 
    <station> 
     ... 
    </station> 

    <station> 
     ... 
    </station> 
</stations> 
을 잘 형성되어야한다다음은 코드

import java.io.FileInputStream; 
import java.lang.reflect.InvocationTargetException; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

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

import org.apache.commons.beanutils.BeanUtils; 
import org.w3c.dom.Document; 
import org.w3c.dom.Element; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 

public class DOMParsarDemo3 { 
    protected DocumentBuilder docBuilder; 
    protected Element root; 

    private static List<AirportStation> stations = new ArrayList<AirportStation>(); 

    public DOMParsarDemo3() throws Exception { 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     docBuilder = dbf.newDocumentBuilder(); 
    } 

    public void parse(String file) throws Exception { 
     Document doc = docBuilder.parse(new FileInputStream(file)); 
     root = doc.getDocumentElement(); 
     System.out.println("root element is :" + root.getNodeName()); 
    } 

    public void printAllElements() throws Exception { 
     printElement(root); 
    } 

    public void printElement(Node node) { 
     if (node.getNodeType() != Node.TEXT_NODE) { 
      Node child = node.getFirstChild(); 
      while (child != null) { 
       if ("station".equals(child.getNodeName())) { 
        NodeList station = child.getChildNodes(); 

        Map<String, String> map = new HashMap<String, String>(); 
        for (int i = 0; i < station.getLength(); i++) { 
         Node s = station.item(i); 
         if (s.getNodeType() == Node.ELEMENT_NODE) { 
          map.put(s.getNodeName(), s.getChildNodes().item(0).getNodeValue()); 
         } 
        } 

        AirportStation airportStation = new AirportStation(); 
        try { 
         BeanUtils.populate(airportStation, map); 
        } catch (IllegalAccessException e) { 
         e.printStackTrace(); 
        } catch (InvocationTargetException e) { 
         e.printStackTrace(); 
        } 

        stations.add(airportStation); 
       } 
       printElement(child); 
       child = child.getNextSibling(); 
      } 
     } 
    } 

    public static void main(String args[]) throws Exception { 
     DOMParsarDemo3 demo = new DOMParsarDemo3(); 
     demo.parse("resources/abc2.xml"); 
     demo.printAllElements(); 

     for (AirportStation airportStation : stations) { 
      System.out.println(airportStation); 
     } 
    } 
} 

POJO에게 도움을

import java.io.Serializable; 

public class AirportStation implements Serializable { 

    private static final long serialVersionUID = 1L; 

    public AirportStation() { 

    } 

    private String station_id; 
    private String state; 
    private String station_name; 
    private String latitude; 
    private String longitude; 
    private String html_url; 
    private String rss_url; 
    private String xml_url; 

    public String getStation_id() { 
     return station_id; 
    } 

    public void setStation_id(String station_id) { 
     this.station_id = station_id; 
    } 

    public String getState() { 
     return state; 
    } 

    public void setState(String state) { 
     this.state = state; 
    } 

    public String getStation_name() { 
     return station_name; 
    } 

    public void setStation_name(String station_name) { 
     this.station_name = station_name; 
    } 

    public String getLatitude() { 
     return latitude; 
    } 

    public void setLatitude(String latitude) { 
     this.latitude = latitude; 
    } 

    public String getLongitude() { 
     return longitude; 
    } 

    public void setLongitude(String longitude) { 
     this.longitude = longitude; 
    } 

    public String getHtml_url() { 
     return html_url; 
    } 

    public void setHtml_url(String html_url) { 
     this.html_url = html_url; 
    } 

    public String getRss_url() { 
     return rss_url; 
    } 

    public void setRss_url(String rss_url) { 
     this.rss_url = rss_url; 
    } 

    public String getXml_url() { 
     return xml_url; 
    } 

    public void setXml_url(String xml_url) { 
     this.xml_url = xml_url; 
    } 

    @Override 
    public String toString() { 
     return "station_id=" + getStation_id() + " station_name=" + getStation_name(); 
    } 

} 
관련 문제