2016-07-28 5 views
3

Я пытаюсь определить лучший способ проанализировать ответ XML, который я получаю от вызова webservice в объект Java. Использование JAXB кажется самым простым способом, но для каждого примера, который я получаю для этого, требуется, чтобы у вас был шаблон Java-класса, который будет представлять собой тип Java, в который преобразуется XML. Мой XML, как показано нижеАнализ XML в объекте Java

<?xml version="1.0" encoding="utf-8" ?> 
    <entry_list version="1.0"> 
     <entry id="main[1]"> <hw highlight="yes" hindex="1">main</hw> <sound><wav>main0001.wav</wav></sound> <pr>ˈmeɪn</pr> <fl>adjective</fl> <lb>always used before a noun</lb> <def><dt>:most important :<sx>chief</sx> <sx>principal</sx> <vi>the <it>main</it> idea/point</vi> <vi>the <it>main</it> goal/purpose</vi> <vi>Speed is the <it>main</it> advantage of this approach.</vi> <vi>The company's <it>main</it> office is located in New York.</vi> <vi>the novel's <it>main</it> character</vi> <vi>driving down the <it>main</it> road/highway</vi> <vi>the <it>main</it> gate/entrance</vi> <vi>This dish can be served as a <phrase>main course</phrase> or appetizer.</vi> <vi>And now for the <phrase>main event</phrase> of the evening!</vi></dt></def> <uro><ure>main*ly</ure> <fl>adverb</fl> <utxt><vi>The reviews have been <it>mainly</it> [=<it>mostly</it>] positive.</vi> <vi>a plant found <it>mainly</it> [=<it>chiefly</it>] in coastal regions</vi> <vi>I don't like the plan, <it>mainly</it> because I think it's too expensive.</vi> <vi>The problems have been <it>mainly</it> minor ones. [=most of the problems have been minor ones]</vi> <vi>They depend <it>mainly</it> on/upon fish for food.</vi></utxt></uro></entry> 
     <entry id="main[2]"> <hw hindex="2">main</hw> <altpr>ˈmeɪn</altpr> <fl>noun</fl> <in><il>plural</il> <if>mains</if></in> <def><sn>1</sn> <sgram>count</sgram> <dt>:the largest pipe in a system of connected pipes <vi>a gas <it>main</it></vi> <vi>a water <it>main</it></vi></dt> <sn>2</sn> <bnote>the mains</bnote> <ssl>Brit</ssl> <sn>a</sn> <dt>:the system of pipes or wires for electricity, gas, or water <vi>My radio runs either off batteries or off <it>the mains</it>.</vi> <un>often used as <it>mains</it> before another noun <vi>We haven't had any <it>mains</it> water/electricity since the storm.</vi></un></dt> <sn>b</sn> <dt>:the place where electricity, gas, or water enters a building or room <vi>Turn off the water at <it>the mains</it>.</vi></dt></def> <dro><dre>in the main</dre> <def><dt>:in general <un>used to say that a statement is true in most cases or at most times <vi>The workers are <it>in the main</it> very capable. [=most of the workers are very capable]</vi> <vi>The weather has <it>in the main</it> been quite good. [=has been quite good most of the time]</vi></un></dt></def></dro></entry> 
     <entry id="main clause"> <hw>main clause</hw> <fl>noun</fl> <in><il>plural</il> <if>⁓ clauses</if></in> <def><gram>count</gram> <sl>grammar</sl> <dt>:a clause that could be used by itself as a simple sentence but that is part of a larger sentence <ca>called also <cat>independent clause</cat></ca> <dx>compare <dxt>coordinate clause</dxt> <dxt>subordinate clause</dxt></dx></dt></def></entry> 
     <entry id="main drag"> <hw>main drag</hw> <fl>noun</fl> <in><il>plural</il> <if>⁓ drags</if></in> <def><gram>count</gram> <sl>US</sl> <sl>informal</sl> <dt>:the main street in a town or city <vi>A carload of teenagers were cruising down the <it>main drag</it>.</vi></dt></def></entry> 
     <entry id="main line"> <hw>main line</hw> <fl>noun</fl> <in><il>plural</il> <if>⁓ lines</if></in> <def><gram>count</gram> <dt>:an important highway or railroad line</dt></def></entry> 
     <entry id="main man"> <hw>main man</hw> <fl>noun</fl> <in><il>plural</il> <if>⁓ men</if></in> <def><gram>count</gram> <sl>US</sl> <sl>informal</sl> <sn>1</sn> <dt>:someone's best male friend <vi>He's still her <it>main man</it>.</vi></dt> <sn>2</sn> <dt>:the most important or admired man in a group <vi>The team has many good players, but he is clearly the <it>main man</it>.</vi></dt></def></entry> 
     <entry id="main squeeze"> <hw>main squeeze</hw> <fl>noun</fl> <in><il>plural</il> <if>⁓ squeezes</if></in> <def><gram>count</gram> <sl>chiefly US slang</sl> <dt>:someone's main girlfriend, boyfriend, or lover <vi>She's my <it>main squeeze</it>.</vi></dt></def></entry> 
     <entry id="main street"> <hw>main street</hw> <fl>noun</fl> <in><il>plural</il> <if>⁓ streets</if></in> <def><sn>1</sn> <sgram>count</sgram> <dt>:the most important street of a U.S. town where there are many stores, banks, etc. <un>often used as a name <vi>The restaurant is at 257 <it>Main Street</it>.</vi></un></dt> <sn>2</sn> <bnote>Main Street</bnote> <sgram>noncount</sgram> <ssl>US</ssl> <dt><un>used to refer to middle-class people in the U.S. who have traditional beliefs and values <vi>What does <it>Main Street</it> think of this policy?</vi></un></dt></def></entry> 
     <entry id="water main"> <hw>water main</hw> <fl>noun</fl> <in><il>plural</il> <if>⁓ mains</if></in> <def><gram>count</gram> <dt>:a large underground pipe that carries water <vi>The <it>water main</it> burst/broke and flooded the street.</vi></dt></def></entry> 
    </entry_list> 

Мой вопрос, я должен определить объект Java, что это будет преобразована в? Что я боюсь, если это так, то происходит, если данные добавляются или удаляются из ответа XML, как он существует на данный момент. Я также пробовал загружать XML в DOM и прогуливать его так, но опять же мне интересно, что произойдет, если элемент будет добавлен или удален?
Я хочу только определенные дочерние узлы, если их родительский узел является определенным значением, поэтому любые указатели на самый простой способ сделать это приветствуются.

+0

Можете ли вы быть более конкретным как то, чего вы хотите добиться, поэтому я могу с уверенностью представить более кураторский ответ –

+0

@ vtd-xml-author Я хочу извлечь все данные в теги , т.е. XXX, если его брат узел содержит определенное значение. Я могу пройти через XML ok (с помощью синтаксического анализатора SAX) и получить нужные мне данные, но я хотел бы сделать это «правильным» способом, поскольку, возможно, я не поддерживаю этот код. – MayoMan

ответ

0

Самый простой способ работы с XML, чтобы сериализовать его к объекту.
Вы можете сделать это с помощью JAXB, вот урок: mykong
Просто определите, как должны выглядеть объекты.
Вот пример:

@XmlRootElement(name = "entry_list") 
public class EntryList { 

    @XmlElement(name = "entry") 
    private List<Entry> entities; 

    public List<Entry> getEntities() { 
     return entities; 
    } 
    public void setLastName(List<Entry> entities) { 
     this.entities = entities; 
    } 
} 

public class Entry { 

    @XmlAttribute 
    private String id; 

    @XmlElement 
    private Sound sound 

    etc 
    ... 

    public String getId() { 
     return id; 
    } 
    public void setId(String id) { 
     this.id = id; 
    } 

    public Sound getSound() { 
     return sound; 
    } 
    public void setSound(Sound sound) { 
     this.sound = sound; 
    } 
} 

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

+0

Спасибо за другие предложения, ребята, но это, по-видимому, является самым прямым способом сделать это, а ремонтопригодность - мой приоритет для этой проблемы. – MayoMan

0

Часто называемый POJO, да, это хорошая идея (может быть, даже необходимость), чтобы иметь его. Он определяет, как ваши данные должны быть представлены как объект. Если данные отсутствуют, поля объекта Java будут пустыми. Следовательно, вы должны определить, что ваш объект Java является максимальной крышкой всех возможных атрибутов.

Там могут быть некоторые библиотеки, которые поставят дополнительные атрибуты в Hashmap (по крайней мере, я знаю, что Джексон может сделать это для JSON, не уверен, XML)

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

+0

С данным XML мне нужно создать всю иерархию Java POJO-класса. Под этим я подразумеваю, что XML - это список объектов Entry, а внутри каждого объекта Entry - подструктуры. Нужно ли создавать классы для каждого? – MayoMan

+0

Думаю, вам нужен только один класс за разную структуру. –

0

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

Например, если вы заинтересованы только в «главном предложении» теге, обработчик будет выглядеть примерно так:

public class MyHandler extends org.xml.sax.helpers.DefaultHandler { 

    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 
     if ("entry".equalsIgnoreCase(localName) && 
       "main clause".equalsIgnoreCase(attributes.getValue("id"))) { 
      // Set a member variable flag 
      // So we know how to process nested tags 
     } 
    } 

    public void endElement(String uri, String localName, String qName) throws SAXException { 
     if ("entry".equalsIgnoreCase(localName)) { 
      // Unset the flag 
     } 
    } 
} 
0

В моем опыте, когда приходится иметь дело с очень сложным XML-документа, его, вероятно, проще:

  1. превратить его в более простой форме
  2. маршалу его в объект, который вы можете работать с

Т.е.позволяет сказать, у вас есть очень сложный XML:

<XML> 
    <SomeElement> 
     <MoreElements> 
      <EvenMoreElements>text</EvenMoreElements> 
     </MoreElements> 
    </SomeElement> 
</XML> 

Шаг № 1: упрощать его с помощью XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <SimpleForm><xsl:value-of select="XML/SomeElement/MoreElements/EvenMoreElements/text()"/></SimpleForm> 
    </xsl:template> 
</xsl:stylesheet> 

Шаг 2. Marshal свой собственный SimpleForm XML в объект Java

Таким образом, вы теряете связь между внешней схемой и вашей внутренней логикой.

0

Я не думаю, что JAXB - лучшее решение здесь ... Лучшее решение основано на XPath, которое позволяет упростить кодирование, не жертвуя ремонтопригодностью кода ... как вы можете видеть ниже в коде, навигационная только одно выражение XPATH, и вся программа о 10+ строк кода, который использует XPath и VTD-XML, BTW ваш пример XML размещен выше, не является хорошо сформированным ...

import com.ximpleware.*; 
public class extractExample { 

    public static void main(String[] args) throws VTDException { 
     // TODO Auto-generated method stub 
     VTDGen vg = new VTDGen(); 
     if(!vg.parseFile("d:\\xml\\sample.xml", false)){ 
      return; 
     } 
     VTDNav vn = vg.getNav(); 
     AutoPilot ap = new AutoPilot(vn); 
     ap.selectXPath("/entry_list/entry/hw[following-sibling::fl='value']/text()"); 
     int i=0; 
     while((i=ap.evalXPath())!=-1){ 
      System.out.println(" hw value are "+vn.toNormalizedString(i)); 
     } 
    } 

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