使用 java 解析 xml 中的元素数组

parsing an array of elements in xml using java

在这里,我使用SAX 方法来解析数组。我遇到一个问题,我无法编写通用代码来解析 xml 的数组类型。我找不到通用方法的解决方案来将其识别为数组并对其进行迭代并将其存储在 List

<bookstore>
  <book category="children">
    <title>Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="web">
    <title>Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>39.95</price>
  </book>
</bookstore>

任何解决方案都会有所帮助。提前致谢

我使用下面的代码。我从:https://github.com/niteshapte/generic-xml-parser

public class GenericXMLParserSAX extends DefaultHandler {

    private ListMultimap<String, String> listMultimap = ArrayListMultimap.create();
    String tempCharacter;   
    private String[] startElements;
    private String[] endElements;

    public void setStartElements(String[] startElements) {
            this.startElements = startElements;
    }

    public String[] getStartElements() {
            return startElements;
    }

    public void setEndElements(String[] endElements) {
            this.endElements = endElements;
    }

    public String[] getEndElements() {
            return endElements;
    }

    public void parseDocument(String xml, String[] startElements, String[] endElements) {
            setStartElements(startElements);
            setEndElements(endElements);

            SAXParserFactory spf = SAXParserFactory.newInstance();
            try {
                    SAXParser sp = spf.newSAXParser();                      
                    InputStream inputStream = new ByteArrayInputStream(xml.getBytes());                     
                    sp.parse(inputStream, this);
            } catch(SAXException se) {
                    se.printStackTrace();
            } catch(ParserConfigurationException pce) {
                    pce.printStackTrace();
            } catch (IOException ie) {
                    ie.printStackTrace();
            }
    }

    public void parseDocument(String xml, String[] endElements) {           
            setEndElements(endElements);

            SAXParserFactory spf = SAXParserFactory.newInstance();
            try {
                    SAXParser sp = spf.newSAXParser();                      
                    InputStream inputStream = new ByteArrayInputStream(xml.getBytes());                     
                    sp.parse(inputStream, this);
            } catch(SAXException se) {
                    se.printStackTrace();
            } catch(ParserConfigurationException pce) {
                    pce.printStackTrace();
            } catch (IOException ie) {
                    ie.printStackTrace();
            }
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            String[] startElements = getStartElements();

            if(startElements!= null){
                    for(int i = 0; i < startElements.length; i++) {
                            if(qName.startsWith(startElements[i])) {                                
                                    listMultimap.put(startElements[i], qName);
                            }
                    }       
            }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
            tempCharacter = new String(ch, start, length);
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {                
            String[] endElements = getEndElements();

            for(int i = 0; i < endElements.length; i++) {
                    if (qName.equalsIgnoreCase(endElements[i])) {
                            listMultimap.put(endElements[i], tempCharacter);                
                    }
            }
    }

    public ListMultimap<String, String> multiSetResult() {            
            return listMultimap;
    }
}

您可以创建一个扩展 DefaultHandler 的自定义处理程序,并使用它来解析您的 XML 并为您生成 List<Book>

处理程序将维护一个 List<Book> 和:

  • 每次遇到书本start标签,都会新建一个Book
  • 每次遇到书本 end 标签时,它都会将此 Book 添加到列表中。

最终它将包含完整的图书列表,您可以通过其 getBooks() 方法

访问它

假设这本书 class:

class Book {
    private String category;
    private String title;
    private String author;
    private String year;
    private String price;
    // GETTERS/SETTERS
}

您可以像这样创建自定义处理程序:

class MyHandler extends DefaultHandler {

    private boolean title = false;
    private boolean author = false;
    private boolean year = false;
    private boolean price = false;

    // Holds the list of Books
    private List<Book> books = new ArrayList<>();
    // Holds the Book we are currently parsing
    private Book book;

    public void startElement(String uri, String localName,String qName, Attributes attributes) {

        switch (qName) {
            // Create a new Book when finding the start book tag
            case "book": {
                book = new Book();
                book.setCategory(attributes.getValue("category"));
            }
            case "title": title = true;
            case "author": author = true;
            case "year": year = true;
            case "price": price = true;
        }
    }

    public void endElement(String uri, String localName, String qName) {
        // Add the current Book to the list when finding the end book tag
        if("book".equals(qName)) {
            books.add(book);
        }
    }

    public void characters(char[] ch, int start, int length) {
        String value = new String(ch, start, length);

        if (title) {
            book.setTitle(value);
            title = false;
        } else if (author) {
            book.setAuthor(value);
            author = false;
        } else if (year) {
            book.setYear(value);
            year = false;
        } else if (price) {
            book.setPrice(value);
            price = false;
        }
    }

    public List<Book> getBooks() {
        return books;
    }
}

然后您使用此自定义处理程序进行解析并检索图书列表

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();

MyHandler myHandler = new MyHandler();
saxParser.parse("/path/to/file.xml", myHandler);
List<Book> books = myHandler.getBooks();