2016-05-19 11 views
0

これは私が持っているクラスです。親を非整列化せずに、XMLのより深い要素を非整列化するにはどうすればよいですか?

@XmlRootElement(name = "XmlParent") 
public class Foo { 

    private String name; 

    @XmlElement 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

<XmlParent> 
    <name>koraytugay</name> 
</XmlParent> 

現在、私は次のコードを使用して、このファイルからオブジェクトを作成することができ、次のように私が持っているサンプルXMLファイルは次のとおりです。

JAXBContext jaxbContext = JAXBContext.newInstance(Foo.class); 
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
final FileReader fileReader = new FileReader(file); 
final Foo foo = (Foo) unmarshaller.unmarshal(fileReader); 
// foo.getName() will be koraytugay which is fine.. 

しかし、私がしたいのは、次のxmlファイルをアンマーシャリングすることです。

クラスへ
<XmlParent> 
    <name>koraytugay</name> 
    <bar> 
     <baz> 
      <qux>00000001</qux> 
     </baz> 
    </bar> 
</XmlParent> 

@XmlRootElement(name = "XmlParent") 
public class Foo { 

    private String name; 
    private String qux; 

    @XmlElement 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @XmlElement 
    public String getQux() { 
     return qux; 
    } 

    public void setQux(String qux) { 
     this.qux = qux; 
    } 
} 

それでは、どのように私は 'バー' と 'バズ' は非整列化しながら、バイパスすることができますか?

+0

http://stackoverflow.com/questions/5044042/jaxb-ignore-element – SpaceTrucker

+0

@SpaceTruckerありがとうございますが、本当に便利ではありません。 –

+0

あなたの質問は分かりません。 'Foo'にunamarshallingするときに表示されるエラーメッセージは何ですか? – SpaceTrucker

答えて

0

XMLの実際の構造と達成したいことに応じて異なります。

XML入力から値がほんの少しだけ必要な場合は、代わりにXPathを使用することもできます。

下記の小さなスニペットを見つけます。あなたはXMLEventReaderを拡張し、それはあなたがスキップしたいXMLタグがある場合は、各イベントにチェックすることができ

import java.io.ByteArrayInputStream; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathFactory; 
import org.w3c.dom.Document; 
... 
String in = "<XmlParent>\n" 
     + " <name>koraytugay</name>\n" 
     + " <bar>\n" 
     + "  <baz>\n" 
     + "   <qux>00000001</qux>\n" 
     + "  </baz>\n" 
     + " </bar>\n" 
     + "</XmlParent>"; 
byte[] bytes = in.getBytes(); 

DocumentBuilder builder = DocumentBuilderFactory.newInstance() 
     .newDocumentBuilder(); 
Document document = builder.parse(new ByteArrayInputStream(bytes)); 
XPathFactory factory = XPathFactory.newInstance(); 
XPath xpath = factory.newXPath(); 
String name = xpath.evaluate("/XmlParent/name", document); 
String qux = xpath.evaluate("/XmlParent/bar/baz/qux", document); 
System.out.println("name = " + name); 
System.out.println("qux = " + qux); 

出力

name = koraytugay 
qux = 00000001 

編集。

XMLイベントリーダー。

import java.util.Set; 
import javax.xml.namespace.QName; 
import javax.xml.stream.XMLEventReader; 
import javax.xml.stream.XMLStreamConstants; 
import javax.xml.stream.XMLStreamException; 
import javax.xml.stream.events.EndElement; 
import javax.xml.stream.events.StartElement; 
import javax.xml.stream.events.XMLEvent; 

public class FilteringlXmlEventReader implements XMLEventReader { 

    final XMLEventReader reader; 
    final Set<QName> qNames; 

    public FilteringlXmlEventReader(XMLEventReader reader, 
      Set<QName> qNames) { 
     this.reader = reader; 
     this.qNames = qNames; 
    } 

    @Override 
    public XMLEvent nextEvent() throws XMLStreamException { 
     while (tagToSkip(reader.peek())) { 
      reader.nextEvent(); 
     } 
     return reader.nextEvent(); 
    } 

    // from XMLEventReader 
    @Override 
    public boolean hasNext() { 
     return reader.hasNext(); 
    } 

    @Override 
    public XMLEvent peek() throws XMLStreamException { 
     return reader.peek(); 
    } 

    @Override 
    public String getElementText() throws XMLStreamException { 
     return reader.getElementText(); 
    } 

    @Override 
    public XMLEvent nextTag() throws XMLStreamException { 
     return reader.nextTag(); 
    } 

    @Override 
    public Object getProperty(String name) throws IllegalArgumentException { 
     return reader.getProperty(name); 
    } 

    // from Iterator 
    @Override 
    public Object next() { 
     return reader.next(); 
    } 

    @Override 
    public void remove() { 
     reader.remove(); 
    } 

    @Override 
    public void close() throws XMLStreamException { 
     reader.close(); 
    } 

    /** 
    * Check if the name of the XML tag which has triggered the passed 
    * event is to be skipped. 
    * 
    * @param event the current event 
    * @return {@code true} the event should be skipped, otherwise 
    * {@code false} 
    */ 
    private boolean tagToSkip(XMLEvent event) { 
     switch (event.getEventType()) { 
      case XMLStreamConstants.START_ELEMENT: 
       StartElement startTag = (StartElement) event; 
       return qNames.contains(startTag.getName()); 
      case XMLStreamConstants.END_ELEMENT: 
       EndElement endTag = (EndElement) event; 
       return qNames.contains(endTag.getName()); 
     } 
     return false; 
    } 
} 

JAXBクラス。

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name = "XmlParent") 
public class FooBar { 

    private String name; 
    private String qux; 

    @XmlElement 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @XmlElement 
    public String getQux() { 
     return qux; 
    } 

    public void setQux(String qux) { 
     this.qux = qux; 
    } 
} 

原則を示すサンプルアプリケーションです。

import java.io.ByteArrayInputStream; 
import java.io.InputStream; 
import java.util.HashSet; 
import java.util.Set; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.namespace.QName; 
import javax.xml.stream.XMLEventReader; 
import javax.xml.stream.XMLInputFactory; 
import sub.optimal.xpath.FooBar; 

public class FilteredUnmarshalling { 

    public static void main(String[] args) throws Exception { 
     String in = "<XmlParent>\n" 
       + " <name>koraytugay</name>\n" 
       + " <bar>\n" 
       + "  <baz>\n" 
       + "   <qux>00000001</qux>\n" 
       + "  </baz>\n" 
       + " </bar>\n" 
       + "</XmlParent>"; 
     byte[] bytes = in.getBytes(); 

     JAXBContext context = JAXBContext.newInstance(FooBar.class); 
     Unmarshaller unmarshaller = context.createUnmarshaller(); 
     XMLInputFactory factory = XMLInputFactory.newInstance(); 

     String[] tagNamesToFilter = {"bar", "baz"}; 
     Set<QName> tagsToFilter = new HashSet<>(); 
     for (String name : tagNamesToFilter) { 
      tagsToFilter.add(new QName(name)); 
     } 

     try (InputStream reader = new ByteArrayInputStream(bytes)) { 
      XMLEventReader xmlEventReader=factory.createXMLEventReader(reader); 
      FooBar fooBar = (FooBar)unmarshaller.unmarshal(
        new FilteringlXmlEventReader(xmlEventReader,tagsToFilter)); 
      System.out.println("name: " + fooBar.getName()); 
      System.out.println("qux : " + fooBar.getQux()); 
     } 
    } 
} 

出力

name: koraytugay 
qux : 00000001 
+0

私は実際に状況を単純化しました。不幸にも、これは私には受け入れられる解決策ではありませんが、感謝しています。 –

+0

@KorayTugay最新の回答をご覧ください。それに基づいて、あなたが望むものを達成できるはずです。 – SubOptimal

関連する問題