无法从XML节点填充列表

无法从XML节点填充列表<Item>

问题描述:

我有一个xml文档来解析哪些嵌套节点,我尝试过我的方式,但无法根据需要完成工作。 XML文档是无法从XML节点填充列表<Item>

<Items> 
    <Item> 
    <MediumImage> 
     <URL>http://ecx.images-amazon.com/images/I/51l7DDD1qNL._SL160_.jpg</URL> 
     <Height Units="pixels">160</Height> 
     <Width Units="pixels">160</Width> 
    </MediumImage> 
    <Title>Fallout 4 Vault Dweller's Survival Guide Collector's Edition: Prima Official Game Guide</Title> 
    <OfferSummary> 
    <LowestNewPrice> 
    <Amount>1952</Amount> 
    </OfferSummary> 
    </Item> 
    . 
    . 
    . 
</Items> 

我已经照

private static NodeList fetchTitle(String requestUrl) { 
     NodeList nodeList = null; 
     try { 
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder db = dbf.newDocumentBuilder(); 
      Document doc = db.parse(requestUrl); 
      nodeList = doc.getElementsByTagName("Title");    
     } catch (Exception e) { 
      System.out.println("Message is " + e.getCause() + "...." + e.getMessage()); 
      throw new RuntimeException(e); 
     } 
     return nodeList; 
    } 

抓取标题节点值和余为

titleList = fetchTitle(requestUrl);   
     for (int i = 0; i < titleList.getLength(); i++) { 
      Node node = titleList.item(i); 
      if (node.getNodeType() == Node.ELEMENT_NODE) { 
       // do something with the current element 
       System.out.println(node.getNodeName()); 
       System.out.println("Signed Title is \"" + node.getTextContent() + "\""); 
       System.out.println(); 
      } 

     } 

金额值打印为在main()来自LowestNewPrice节点为

private static NodeList fetchPrice(String requestUrl) { 
     NodeList nodeList = null; 
     try { 
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder db = dbf.newDocumentBuilder(); 
      Document doc = db.parse(requestUrl); 
      nodeList = doc.getElementsByTagName("LowestNewPrice");   
     } catch (Exception e) { 
      System.out.println("Message is " + e.getCause() + "...." + e.getMessage()); 
      throw new RuntimeException(e); 
     } 
     return nodeList; 
    } 

,我在main()作为

priceList = fetchPrice(requestUrl); 

     for (int i = 0; i < priceList.getLength(); i++) { 
      Node node = priceList.item(i).getFirstChild(); 
      if (node.getNodeType() == Node.ELEMENT_NODE) { 
       // do something with the current element 
       System.out.println(node.getNodeName()); 
       System.out.println("Signed Price is \"" + node.getTextContent() + "\""); 
       System.out.println(); 
      } 

     } 

打印通过上面的代码我得到的所有标题第一值,然后我得到金额值分别,但我真正想要的是有一个POJO类作为

public class Item { 

    String title; 
    String price; 

    public String getTitle() { 
     return title; 
    } 
    public void setTitle(String title) { 
     this.title = title; 
    } 
    public String getPrice() { 
     return price; 
    } 
    public void setPrice(String price) { 
     this.price = price; 
    } 

} 

,并使用setTitle(), setPrice()增加值项的对象,并返回一个List<Item> 请任何帮助。

可能请尝试此解决方案。 解析您的数据,并添加到List<Item>为:

public static Document fetchRequiredData(String src) { 
    Document doc = null; 

    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder parser; 

    try { 
     parser = dbFactory.newDocumentBuilder(); 
     doc= parser.parse(src); 
    } catch (ParserConfigurationException e) { 
     e.printStackTrace(); 
    } catch (SAXException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    return doc; 
} 

public static List<Item> parseItemInfo(Document doc){ 

    List<Item> items = new ArrayList<Item>(); 
    NodeList itemNodeList = doc.getElementsByTagName("Item");  

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

     Node titleNode = doc.getElementsByTagName("Title").item(i); 
     Node priceNode = doc.getElementsByTagName("LowestNewPrice").item(i).getFirstChild(); 

     if (titleNode.getNodeType() == Node.ELEMENT_NODE || priceNode.getNodeType() == Node.ELEMENT_NODE) { 
      Item item = new Item(); 
      item.setDesc(titleNode.getTextContent()); 
      item.setPrice(priceNode.getTextContent()); 
      items.add(item); 
     } 
    } 
    return items; 
} 

现在您的清单准备在main()方法测试作为

public static void main(String[] args) { 
    List<Item> items = parseItemInfo(fetchRequiredData(requestUrl)); 
    System.out.println("Printing List<Item> contents ..."); 
    for (Item item : items) { 
     System.out.println("Title is " + item.getTitle()); 
     System.out.println("Price is " + item.getPrice()); 
     System.out.println(); 
    } 
} 

希望这一个帮助。

+0

这是这样做的一种有效的方式,但它会在情况下,可以有''元件没有''或'<lowestnewprice>'元素失败。 – <span class="text-secondary"> <small> <a rel="noopener">Titus</a></small></span> <span></span> </lowestnewprice>

+1

正如所提供的_xml stub_问题所示,我猜想不太可能存在任何可能存在''元素而没有''或'<lowestnewprice>'元素的情况。谢谢你的考虑,但为了避免这种情况,可以在__improved__上面回答,我想这个答案是__easy__来读__,_write_,_compile_并完成所需的工作。是不是......? – <span class="text-secondary"> <small> <span></span> </small> </span> </lowestnewprice>

+0

你是绝对正确的,就像我曾经说过的“这是一种有效的方法”,我只是想指出这一点,让OP意识到它,所以如果他的用例包含那些类型的话,他可以修改代码项目。 – Titus

目前看来,你的价格和标题分成2所列出,如果您想将项目的价格和标题存储到一个单一的Item对象,你可以做这样的事情:

public class Item { 

    public static void main(String[] args) { 
     ArrayList<Item> items = new ArrayList<Item>(); 
     try { 
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder db = dbf.newDocumentBuilder(); 
      Document doc = db.parse(new File("items.xml")); 
      NodeList itemElements = doc.getElementsByTagName("Item"); 

      for (int i = 0; i < itemElements.getLength(); i++) { 
       Node itemElement = itemElements.item(i); 
       NodeList itemChildren = itemElement.getChildNodes(); 

       Item item = new Item(); 

       for (int j = 0; j < itemChildren.getLength(); j++) { 
        Node n = itemChildren.item(j); 
        if (n.getNodeName().equalsIgnoreCase("title")) { 
         item.setTitle(n.getTextContent()); 
        } else if (n.getNodeName().equalsIgnoreCase("OfferSummary")) { 
         NodeList offerChildren = n.getChildNodes(); 
         for (int k = 0; k < offerChildren.getLength(); k++) { 
          Node offerChild = offerChildren.item(k); 
          if (offerChild.getNodeName().equalsIgnoreCase("LowestNewPrice")) { 
           item.setPrice(offerChild.getTextContent()); 
          } 
         } 
        } 
       } 
       items.add(item); 

      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     System.out.println("items: " + items); 
    } 

    String title; 
    String price; 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public String getPrice() { 
     return price; 
    } 

    public void setPrice(String price) { 
     this.price = price; 
    } 

    @Override 
    public String toString() { 
     return "Title: " + title + " Price: " + price; 
    } 

} 

它所做的就是从XML获取所有<Item>元素,并循环遍历它们以获取项目的标题和价格。

您可以通过使用JAXBContext来实现。首先创建Item类。

@XmlRootElement(name = "Items") 
@XmlAccessorType(value = XmlAccessType.FIELD) 
public class Items 
{ 
    @XmlElement(name = "Item") 
    private List<Item> item; 

    public void setItem(List<Item> itemList) 
    { 
     this.item = itemList; 
    } 
    public List<Item> getItem() 
    { 
     return this.item; 
    } 
} 

@XmlRootElement(name = "Item") 
@XmlAccessorType(vallue = XmlAccessType.FIELD) 
public class Item 
{ 
    @XmlElement(name = "MediumImage") 
    private MediumImage image; 
    @XmlElement(name = "Title") 
    private String title; 
    @XmlElement(name = "OfferSummary") 
    private OfferSummary summary; 

    getters(); 
    setters(); 
} 

@XmlRootElement(name = "MediumImage") 
@XmlAccessorType(value = XmlAccessType.FIELD) 
public class MediumImage 
{ 
    @XmlElement(name = "URL") 
    private String url; 
    .... 
} 

@XmlRootElement(name = "OfferSummary") 
@XmlAccessorType(value = XmlAccessType.FIELD) 
public class OfferSummary 
{ 
    @XmlElement(name = "LowestNewPrice") 
    private LowestNewPrice lowestPrice; 
    .... 
} 

然后从主要方法使用编组器和unmarshaller方法。

public static void main(String[] args) 
{ 
    File xmlFile = new File("file path"); 
    JAXBContext context = JAXBContext.newInstance(Items.class); 
    //To get POJO from xml 
    Unmarshaller unmarshaller = context.createUnmarshaller(); 
    Items items = (Items) unmarshaller.unmarshal(xmlFile); 
}