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

Can not populate List<Item> from XML nodes

我有一个 xml 文档来解析哪些嵌套节点我已经尝试过但无法按要求完成工作。 XML 文档是

<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>

我已将 Title 节点值提取为

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;
    }

并且我在 main() 中打印为

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();
            }

        }

Amount值来自LowestNewPrice Node as

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();
            }

        }

通过上面的代码,我先得到所有的 Title 值,然后分别得到 Amount 值,但我真正想要的是POJO class as

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() 和 return 向 Item 对象添加值 List<Item> 请帮忙。

目前您似乎将价格和标题分成了 2 个列表,如果您想将商品的价格和标题存储到一个 Item object 中,您可以执行类似这个:

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> 元素并循环遍历它们以获取商品的标题和价格。

可能请尝试此解决方案。 解析您的数据并添加到 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();
     }
}

希望这对您有所帮助。

您可以通过使用 JAXBContext 来实现。首先创建项目 class.

@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;
    ....
}

然后从 main 方法使用 marshaller 和 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);
}