парсинг XML в Java с одинаковыми родительскими и дочерними тегами - PullRequest
1 голос
/ 18 марта 2011

Я пытался создать приложение для Android, которое получает данные с сервера Labview RestFUL.До сих пор мне удавалось добиваться немалых успехов, но я застрял, когда мне нужно разобрать данные из массива (названного Вероятностью).Ниже показан фрагмент кода XML:

<Response>
    <Terminal>
        <Name>Push</Name>
        <Value>77.678193</Value>
    </Terminal>
    <Terminal>
        <Name>Pull</Name>
        <Value>153.621879</Value>
    </Terminal>
(snip)
    <Terminal>
        <Name>Probability</Name>
        <Value>
            <DimSize>480</DimSize>
            <Name>effect</Name>
            <Value>0.000000</Value>
            <Name>effect</Name>
            <Value>0.000000</Value>
            <Name>effect</Name>
(snip)
        </Value>
    </Terminal>
</Response>

Как вы можете видеть, LabView использует вложенный тег значения.

Я использовал стандартные методы анализа XML, но это не помогло(Если я ищу «Значения» в родительском узле, он возвращает тот же родительский узел).Так что я начинаю использовать больше креативных техник без хороших результатов.Например, приведенный ниже код, я звоню if ( lName == "Value") только для того, чтобы узнать, что для lName установлено значение Null.

Есть какие-нибудь советы?

InputStream firstData = null;
URL url = null;
try {
    url = new URL(urlString);
} catch (MalformedURLException e2) {
    // TODO Auto-generated catch block
    e2.printStackTrace();
} 
int response = -1;


try {
    URLConnection conn = url.openConnection();
    Document doc = null;
    DocumentBuilderFactory dbf = 
        DocumentBuilderFactory.newInstance();
    DocumentBuilder db;

    HttpURLConnection httpConn = (HttpURLConnection) conn;
    httpConn.setAllowUserInteraction(false);
    httpConn.setInstanceFollowRedirects(true);
    httpConn.setRequestMethod("GET");
    httpConn.connect(); 

    response = httpConn.getResponseCode();                 
    if (response == HttpURLConnection.HTTP_OK) {
        firstData = httpConn.getInputStream();                                 
    }                     

    try {
        db = dbf.newDocumentBuilder();
        doc = db.parse(firstData);
    } catch (ParserConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }        

    doc.getDocumentElement().normalize(); 

    NodeList terminalNodes = doc.getElementsByTagName("Terminal"); 

    for (int i = 0; i < 4; i++) { 
        Node singleTerminalNode = terminalNodes.item(i); 
        if (singleTerminalNode.getNodeType() == Node.ELEMENT_NODE) 
        {            
            Element firstLevel = (Element) singleTerminalNode;

            NodeList value1Nodes = (firstLevel).getElementsByTagName("Value");

            Element value1Element = (Element) value1Nodes.item(0);

            if (i<FIRST_SET){
                NodeList digit1Nodes = ((Node) value1Element).getChildNodes();
                hinde[i] = Double.parseDouble(((Node) digit1Nodes.item(0)).getNodeValue());
            }
            else 
                {
                NodeList value1Children = ((Node) value1Element).getChildNodes();

                int henry = value1Children.getLength();
                int counter = 0;
                String lName;



                for (int j = 0; i < henry; j++){                

                    Element digit2Element = (Element) value1Children.item(j);
                    lName = digit2Element.getLocalName();
                    if ( lName == "Value")
                    {
                    NodeList digit2Nodes = ((Node) digit2Element).getChildNodes();
                    sweep[counter] = Double.parseDouble(((Node) digit2Nodes.item(0)).getNodeValue());
                    counter ++;
                    }
                }
                }
        } 
    }   
} catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();            
}

Ответы [ 2 ]

2 голосов
/ 18 марта 2011

Я полагаю, что это можно сделать с помощью синтаксического анализатора DOM, но его проще реализовать с помощью синтаксического анализатора SAX или STAX (он также будет иметь меньший оттиск памяти!).

http://download.oracle.com/javase/1.4.2/docs/api/javax/xml/parsers/SAXParser.html

http://download.oracle.com/javaee/5/tutorial/doc/bnbem.html

С SAX вы создаете обработчик, который будет получать события, когда синтаксический анализатор достигает определенных точек в документе. С тегами, которые могут быть встроены, вы можете использовать свой обработчик для поддержания состояния курсора. Например, когда вы видите первый тег, вы можете иметь int, представляющий «уровень» тега.

С STAX вы выполняете потоковую передачу событий, и вам нужно иметь дело только с теми событиями, которые вас интересуют. Если вас интересуют «события начального элемента», вы можете получить их и сохранить состояние курсора подобно тому, как вы бы с парсером SAX.

0 голосов
/ 19 марта 2011

Как уже упоминал nicholas.hauschild, вы можете использовать SAX Parser для этого. Но я не думаю, что вам нужна переменная уровня, чтобы различать два тега.

Всякий раз, когда есть данные, которые нужно прочитать, он будет вызывать метод characters (), и вы можете прочитать значения из этого. Так как родительский тег <Value> не имеет собственных данных (кроме вложенных тегов), он не вызывает метод characters ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...