2012-10-11 5 views
3

У меня есть следующий код XML:Извлечение данных из XML с помощью Java

<CampaignFrameResponse 
    xmlns="http://Qsurv/api" 
    xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <Message>Success</Message> 
    <Status>Success</Status> 
    <FrameHeight>308</FrameHeight> 
    <FrameUrl>http://delivery.usurv.com?Key=a5018c85-222a-4444-a0ca-b85c42f3757d&amp;ReturnUrl=http%3a%2f%2flocalhost%3a8080%2feveningstar%2fhome</FrameUrl> 
</CampaignFrameResponse> 

То, что я пытаюсь сделать, это извлечь узлы и присвоить их переменной. Так, например, у меня будет переменная с именем FrameHeight, содержащая значение 308.

Это код Java я до сих пор:

private void processNode(Node node) { 
    NodeList nodeList = node.getChildNodes(); 
    for (int i = 0; i < nodeList.getLength(); i++) { 
     Node currentNode = nodeList.item(i); 
     if (currentNode.getNodeType() == Node.ELEMENT_NODE) { 
      //calls this method for all the children which is Element 
      LOG.warning("current node name: " + currentNode.getNodeName()); 
      LOG.warning("current node type: " + currentNode.getNodeType()); 
      LOG.warning("current node value: " + currentNode.getNodeValue()); 
      processNode(currentNode); 
     } 
    } 

} 

Это выводит узловые имена, тип и значение, но то, что это лучший способ присвоения каждого из значений к соответствующему названию переменному ? например int FrameHeight = 308?

Это мой обновленный код, где переменная nodeValue сохраняет возвращающийся нуль:

processNode(Node node) { 
NodeList nodeList = node.getChildNodes(); 
for (int i = 0; i < nodeList.getLength(); i++) { 
    Node currentNode = nodeList.item(i); 
    if (currentNode.getNodeType() == Node.ELEMENT_NODE) { 
     //calls this method for all the children which is Element 
     String nodeName = currentNode.getNodeName(); 
     String nodeValue = currentNode.getNodeValue(); 
     if(nodeName.equals("Message")) { 
      LOG.warning("nodeName: " + nodeName); 
      message = nodeValue; 
      LOG.warning("Message: " + message); 
     } 
     else if(nodeName.equals("FrameHeight")) { 
      LOG.warning("nodeName: " + nodeName); 
      frameHeight = nodeValue; 
      LOG.warning("frameHeight: " + frameHeight); 
     } 
     processNode(currentNode); 
    } 
} 

}

ответ

1

Поддержка Xstream wont в вашем случае, его можно использовать для преобразования объекта в xml, а затем вернуться обратно. Если ваш xml создается из экземпляра класса CampaignFrameResponse, вы можете использовать xstream.

В противном случае вы просто проверить, как

String nodeName = currentNode.getNodeName() 
String nodeValue = currentNode.getNodeValue() ; 
if(nodeName.equals("Message")){ 
    message = nodeValue ; 
} else if(nodeName.equals("FrameHeight") { 
    frameHeight = nodeValue ; 
} 

Вам нужно разобрать, если вам нужно INT значение.

+0

Спасибо за это. По какой-то причине переменная nodeValue сохраняет значение null. Я добавил обновленный код до конца исходного вопроса. – Victoria

2

Вы можете использовать DOM, SAX, Pull-Parser, но затем его хорошо идти со следующим API.

-JAXP & JAXB

-Castor

Например: DOM PARSING

DocumentBuilderFactory odbf = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder odb = odbf.newDocumentBuilder(); 
      InputSource is = new InputSource(new StringReader(xml)); 
      Document odoc = odb.parse(is); 
      odoc.getDocumentElement().normalize(); // normalize text representation 
      System.out.println ("Root element of the doc is " + odoc.getDocumentElement().getNodeName()); 
      NodeList LOP = odoc.getElementsByTagName("response"); 

       Node FPN =LOP.item(0); 
       try{ 
       if(FPN.getNodeType() == Node.ELEMENT_NODE) 
        { 

        Element token = (Element)FPN; 

        NodeList oNameList1 = token.getElementsByTagName("user_id"); 
        Element firstNameElement = (Element)oNameList1.item(0); 
        NodeList textNList1 = firstNameElement.getChildNodes(); 
        this.setUser_follower_id(Integer.parseInt(((Node)textNList1.item(0)).getNodeValue().trim())); 
        System.out.println("#####The Parsed data#####"); 
        System.out.println("user_id : " + ((Node)textNList1.item(0)).getNodeValue().trim()); 
        System.out.println("#####The Parsed data#####"); 
0

Я хотел бы предложить, чтобы разобрать XML непосредственно (если вы вынуждены делать это), но вместо этого использовать внешнюю библиотеку, например http://x-stream.github.io/. Идея состоит в том, что вы можете создать объект, представляющий вашу xml-схему, и библиотека заполнит этот объект для вас.

0

Предлагаю использовать - x-stream.github.io - с некоторой демаркационной аннотацией вы можете быстро создать объект из XML с очень маленьким кодированием.

2

Я работаю с XML в Java некоторое время (более десяти лет) и пробовал много альтернатив (пользовательский синтаксический анализ текста, собственные API, SAX, DOM, Xmlbeans, JAXB и т. Д.). Я узнал пару вещей:

  • Придерживайтесь стандартов. Никогда не используйте проприетарный API, а стандартный Java API (JAXP, который включает SAX, DOM, Stax и т. Д.). Ваш код будет более переносимым и универсальным и не будет меняться, когда изменяется версия библиотеки XML и нарушает совместимость (что происходит очень часто).
  • Не спешите и изучайте технологии XML. Я бы рекомендовал всестороннее знание, по крайней мере, XSD, XSLT и XPath (необходимых для XSLT). Если у вас нет времени, то сосредоточьтесь на XSD.
  • Воспользуйтесь возможностью автоматического генерации/анализа XML-кода, когда это возможно. Это подразумевает знание XSD. В долгосрочной перспективе это оправдывает первоначальные усилия, с течением времени код намного удобнее обслуживать, синтаксический анализ/марсаллинг сильно оптимизирован (обычно это больше, чем если вы используете «ручные» API JAXP) и проверку XML (у вас уже есть XSD) могут быть выполнены (меньше кода проверки, безопасности от плохо сформированного XML, разбивающего ваше приложение, меньше усилий по интеграции). И самое лучшее, вы только пишете XSD-код, почти весь код Java, который вам понадобится для обработки данных (Java Beans), будет создан для вас.

Знаете ли вы, что я использую генерацию кода всякий раз, когда мне приходится разбирать некоторые XML. Стандарт для этого - JAXB (xmlbeans мертв, а другие альтернативы могут быть не столь зрелыми или широко используемыми). В вашем случае я бы определил XSD, который определил ваш документ как можно более подробно (т. Е. Если вы используете String, который может иметь только несколько значений, не используйте тип «xs: string», а перечисленный). Это может выглядеть следующим образом:

<xs:schema attributeFormDefault="unqualified" 
    elementFormDefault="qualified" targetNamespace="http://Qsurv/api" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="CampaignFrameResponse"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element type="xs:string" name="Message" /> 
       <xs:element type="Status" name="Status" /> 
       <xs:element type="xs:short" name="FrameHeight" /> 
       <xs:element type="xs:anyURI" name="FrameUrl" /> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 

    <<xs:simpleType name="Status"> 
     <xs:annotation> 
      <xs:appinfo> 
       <jaxb:typesafeEnumClass> 
        <jaxb:typesafeEnumMember name="SUCCESS" 
         value="Success" /> 
        <jaxb:typesafeEnumMember name="FAILURE" 
         value="Failure" /> 
       </jaxb:typesafeEnumClass> 
      </xs:appinfo> 
     </xs:annotation> 
     <xs:restriction base="xs:string"> 
      <xs:enumeration value="Success" /> 
      <xs:enumeration value="Failure" /> 
     </xs:restriction> 
    </xs:simpleType> 
</xs:schema> 

Теперь это вопрос об использовании JAXB инструментов (см XJC опции компилятора) для генерации коды и увидеть пару примеров о том, как маршал/распаковать сгенерированную Java Beans из/в XML ,

+0

Почему вы говорите: «xmlbeans мертв»? – marcolopes

1

Вы можете, конечно, создать карту значений имен и обновить карту по мере прохождения XML. В конце разбора вы можете искать конкретный ключ на карте. Java не позволяет вам создавать переменные программно, поэтому вы не сможете генерировать переменную с ее именем на основе данных XML.

В отличие от стиля и удобочитаемости, решение о заполнении структур данных из XML зависит от того, насколько четко определяется XML и насколько его схема могла бы измениться в будущем. Вы можете задать себе такие вопросы, как: Может ли изменение имени узла в будущем? Могут ли быть представлены подразделы XML, которые будут описывать этот раздел? Это может помочь вам выбрать определенный парсер (API-интерфейсы SAX/DOM или более высокого уровня).

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

Смежные вопросы