1

这是我的 XML:

<questions>
    <question>
        <title>What eth speed?</title>
        <options>
            <option>10</option>
            <option>100</option>
            <option>1000</option>
        </options>
        <tagtochange>change this tag</tagtochange>
    </question>
    <question>
        <title>What duration?</title>
        <options>
            <option>Null</option>
        </options>
        <tagtochange>duration</tagtochange>
    </question>
</questions>

我正在尝试在 java 中解析它,但我无法取出内部选项标签,我要么一无所获,要么从所有问题中得到一切!

这是我的代码:

DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db =dbf.newDocumentBuilder();
Document doc=db.parse("questions.xml");
NodeList nl = doc.getElementsByTagName("question");
for(int i=0;i<nl.getLength();i++)
    {
      NodeList titleNlc=    doc.getElementsByTagName("title");
      Element titleElements=(Element)titleNlc.item(i);
      String titleTagValue=titleElements.getChildNodes().item(0).getNodeValue();

      NodeList optionsNlc=    doc.getElementsByTagName("options");
      Element optionsElements=(Element)optionsNlc.item(i);
      String optionsTagValue=optionsElements.getChildNodes().item(0).getNodeValue();  

      NodeList tagNlc=    doc.getElementsByTagName("tagtochange");
      Element tagElements=(Element)tagNlc.item(i);
      String tagTagValue=tagElements.getChildNodes().item(0).getNodeValue();

      System.out.println("title :"+titleTagValue);    
      System.out.println("option :"+optionsTagValue);    
      System.out.println("tagtochange :"+tagTagValue);
      System.out.println(optionsElements.toString());
    }

谢谢你的帮助!

编辑:我计划用这些数据动态创建一个表单,所以要么没有选项,它会创建一个文本框,要么没有选项,它会创建一个组合框。

4

3 回答 3

3

从这篇文章中找到了我一直在寻找的答案:parsing Xml with NodeList and DocumentBuilder

我稍微编辑了我的xml:

<questions>
    <question title="What eth speed?" tag="tagEth">
        <options>
            <option>10</option>
            <option>100</option>
            <option>1000</option>
        </options>
    </question>
    <question title="What duration?" tag="tagDuration">
        <options>
            <option>Null</option>
        </options>
    </question>
</questions>

这是java:

for(int i=0;i<questionList.getLength();i++)
    {
        Element question = (Element) questionList.item(i);
        String questionText = question.getAttribute("title");
        String tagText = question.getAttribute("tag");
        System.out.println("Question :"+questionText);
        System.out.println("tag :"+tagText);

        NodeList optionList = question.getElementsByTagName("option");
        for (int j = 0; j < optionList.getLength(); ++j)
        {
            Element option = (Element) optionList.item(j);
            String optionText = option.getFirstChild().getNodeValue();
            System.out.println("Option :"+optionText);
        }
    }

这给出了这个输出:

Question :What eth speed?
tag :tagEth
Option :10
Option :100
Option :1000
Question :What duration?
tag :tagDuration
Option :Null
于 2012-11-19T16:32:20.320 回答
1

一个简单的 Java Parser 将帮助您:

import java.util.Vector;

/**
 * XMLSimpleTouch is a simple xml parser, it allow to retrive only tags bodies.
 * 
 * Example XML file (in exampleXmlString variable): <?xml?> <books> <book>
 * <title>book1 title</title> <isbn>1122334455</isbn> </book> <book>
 * <title>book2 title</title> <isbn>2233445566</isbn> </book> </books>
 * 
 * Example of use: XMLSimpleTouch xml = new XMLSimpleTouch(exampleXmlString);
 * xml.getString("books/book/title"); // return "book1 title" //NOW WE LOOK FOR
 * SECOND BOOK xml.getString("books/book[2]/title"); // return "book2 title"
 * 
 * path "books/book[1]/title" is equal: "books/book/title"
 * 
 *         TODO: 1) add attributes, 2) add parsing from stream
 */
public class XMLSimpleTouch {
    private String defaultNodeValue = null;

    /** XML string to parse */
    private String strXML = null;

    /**
     * Constructor
     * 
     * @param xml
     *            XML string to parse
     */
    public XMLSimpleTouch(String xml) {
        this.strXML = xml;
    }

    /**
     * Retrive string value between tags from given path. XML file was given in
     * constructor, default value is null.
     * 
     * @param XMLpath
     *            path to string
     * @return value in given path or default value if path not found
     */
    public String getText(String XMLpath) {
        return getText(XMLpath, null, null);
    }

    /**
     * Retrive string value between tags from given path.
     * 
     * @param XMLpath
     *            path to string
     * @param defaultValue
     *            default value to return if path not found
     * @return value in given path or default value if path not found
     */
    public String getText(String XMLpath, String defaultValue) {
        this.defaultNodeValue = defaultValue;
        return getText(XMLpath, defaultValue, null);
    }

    /**
     * Retrive string value between tags from given path.
     * 
     * @param XMLpath
     *            path to string
     * @param defaultValue
     *            default value to return if path not found
     * @param XMLFile
     *            xml string to parse instead of given in constructor
     * @return value in given path or default value if path not found
     */
    public String getText(String XMLpath, String defaultValue, String XMLFile) {
        if (strXML == null)
            return null;
        try {
            /** Disasembly path */
            Object[][] path = dissasemblyPath(XMLpath);
            /** XML string to parse */
            String result = strXML;
            /** If given xml string is null use xml given in constructor */
            if (XMLFile != null)
                result = XMLFile;
            /** Extract value from path */
            for (int i = 0; i < path.length; i++) {
                /** Get element from path */
                String element = (String) path[i][0];
                /** Get occurence we search */
                int occurence = ((Integer) path[i][1]).intValue();
                /** Extract element */
                result = extractElement(element, occurence, result);
            }
            /** Return extracted value */
            return result;
        } catch (Exception e) {
        }
        return defaultValue;
    }

    /**
     * Search for given element and return its body.
     * 
     * @param element
     * @param occurence
     * @param xmlStr
     *            string where we look for element
     * @return
     */
    private String extractElement(String element, int occurence, String xmlStr) {
        int index = 0;
        String elString = null;
        do {
            int elNameLength = element.length() + 2;
            int elStart = xmlStr.indexOf("<" + element + ">", index);
            int elEnd = xmlStr.indexOf("</" + element + ">", elStart
                    + elNameLength);
            // returns 'defaultNodeValue' if the specifed child node(eg:
            // books/book[4]) not found or none of childs are present
            if (elStart == -1 || elEnd == -1)
                return defaultNodeValue;
            elString = xmlStr.substring(elStart + elNameLength, elEnd);
            occurence--;
            index = elEnd + elNameLength;
        }
        /** Repeat until occurence is 0 or null is given */
        while (occurence > 0 && elString != null);
        return elString;
    }

    /**
     * Disassembly path to elements and its occurences
     * 
     * @param XMLpath
     *            path to disassembly
     * @return Object[][] array, first element in array is path element, second
     *         is occurence.
     */
    private Object[][] dissasemblyPath(String XMLpath) {
        /** Split path */
        String[] str = split(XMLpath, "/");
        /** Create array to keep elements and occurences */
        Object[][] resultArray = new Object[str.length][2];
        /** Fill array with elements from path */
        for (int i = 0; i < str.length; i++) {
            /** Get path piece */
            String s = str[i];
            String occurence = "1";
            /** Search for occurence */
            int occur1 = s.indexOf("[");
            int occur2 = s.indexOf("]", occur1 + 1);
            if (occur1 != -1 && occur2 != -1) {
                /** Occurence defined */
                occurence = s.substring(occur1 + 1, occur2);
                resultArray[i][0] = s.substring(0, occur1);
                resultArray[i][1] = new Integer(Integer.parseInt(occurence));
            } else {
                /** No occurence defined, using default */
                resultArray[i][0] = s;
                resultArray[i][1] = new Integer(1);
            }
        }
        return resultArray;
    }

    public static String[] split(String source, String separator) {
        Vector<String> vector = new Vector<String>();
        String[] strings = null;
        while (true) {
            int index = source.indexOf(separator);

            if (index == -1) {
                vector.addElement(source);
                break;
            }
            vector.addElement(source.substring(0, index));
            source = source.substring(index + separator.length());
        }

        strings = new String[vector.size()];
        for (int i = 0; i < vector.size(); ++i) {
            strings[i] = ((String) vector.elementAt(i));
        }

        return strings;
    }

    public static void main(String[] args) {
        String xml = "<questions>" + 
        "    <question>" + 
        "        <title>What eth speed?</title>" + 
        "        <options>" + 
        "            <option>10</option>" + 
        "            <option>100</option>" + 
        "            <option>1000</option>" + 
        "        </options>" + 
        "        <tagtochange>change this tag</tagtochange>" + 
        "    </question>" + 
        "    <question>" + 
        "        <title>What duration?</title>" + 
        "        <options>" + 
        "            <option>Null</option>" + 
        "        </options>" + 
        "        <tagtochange>duration</tagtochange>" + 
        "    </question>" + 
        "</questions>";

        XMLSimpleTouch xmlParser = new XMLSimpleTouch(xml);

        // traversing the first question 
        System.out.println(xmlParser.getText("questions/question[1]/options/option[1]"));
        System.out.println(xmlParser.getText("questions/question[1]/options/option[2]"));
        System.out.println(xmlParser.getText("questions/question[1]/options/option[3]"));
        System.out.println(xmlParser.getText("questions/question[1]/options/option[4]")); // this will be null

        // traversing the second question       
        System.out.println(xmlParser.getText("questions/question[2]/options/option[1]"));
        System.out.println(xmlParser.getText("questions/question[2]/options/option[2]"));
        System.out.println(xmlParser.getText("questions/question[2]/options/option[3]"));
        System.out.println(xmlParser.getText("questions/question[2]/options/option[4]"));


    }

}

您还可以使用简单的逻辑进行迭代,将边界/退出条件作为null值。

编辑

添加了迭代逻辑以获取所有option标签值questions

for(int i=1;;i++)
{
    String value = xmlParser.getText("questions/question["+i+"]");
    if(value==null)break;
    for(int j=1;;j++)
    {
        value = xmlParser.getText("questions/question["+i+"]/options/option["+j+"]");
        if(value==null)break;
        System.out.println(value);
    }
}
于 2012-11-19T13:48:09.307 回答
0
NodeList optionsNlc=    doc.getElementsByTagName("options");
Element optionsElements=(Element)optionsNlc.item(i);

NodeList optionNlc = optionsElements.getElementsByTagName("option");
// process the list of child nodes

您还可以使用:

NodeList optionNlc = optionsElements.getChildNodes();

因为你知道 xml 应该是什么样子

于 2012-11-19T13:36:10.317 回答