JAXBで非名前空間のnilおよびデータ型属性を設定する方法

アレックスディーン:

ScalaでJAXBを使用していますが、私のマーシャリングコードは次のようになります。

def marshalToXml(): String = {
  val context = JAXBContext.newInstance(this.getClass())
  val writer = new StringWriter
  context.createMarshaller.marshal(this, writer)
  writer.toString()
}

次に、null許容要素に対して、JAXBマーシャリングによるnullフィールドを使用した注釈@XmlElement(nillable = true)使用していますこれにより、次のようなXML出力が得られます。

<name>Alex Dean</name>
<customerReference xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<quantity>1</quantity>
<createdAt>2011-05-14T00:00:00+03:00</createdAt>

これは良いスタートですが、これらのフィールドをマーシャリングしたいのは次のとおりです。

<name>Alex Dean</name>
<customerReference nil="true"/>
<quantity type="integer">1</quantity>
<createdAt type="datetime">2011-05-14T00:00:00+03:00</createdAt>

つまり、名前空間の属性とプレフィックスを削除し、文字列以外のすべてに明示的なXMLデータ型属性を追加したいと思います。それはおそらく非常に簡単ですが、JAXBのドキュメントでその方法を見つけることができないようです。

助けてくれてありがとう!

ブドゥアン:

StAXパーサーでJAXBを使用して、以下を実行できます。

お客様

ドメインモデルの各プロパティは、でマッピングされ@XmlElement(nillable=true, type=Object.class)ます。を設定するtype=Object.classと、xsi:type属性が強制的に書き出されます。

package forum8198945;

import java.util.Date;  
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Customer {

    private String name;
    private Customer customerReference;
    private Integer quantity;
    private Date createdAt;

    @XmlElement(nillable=true, type=Object.class)
    public String getName() {
        return name;
    }

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

    @XmlElement(nillable=true, type=Object.class)
    public Customer getCustomerReference() {
        return customerReference;
    }

    public void setCustomerReference(Customer customerReference) {
        this.customerReference = customerReference;
    }

    @XmlElement(nillable=true, type=Object.class)
    public Integer getQuantity() {
        return quantity;
    }

    public void setQuantity(Integer quantity) {
        this.quantity = quantity;
    }

    @XmlElement(nillable=true, type=Object.class)
    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

}

XMLStreamWriterWrapper

XMLStreamWriterXMLに書き込みたくないすべての情報を削除するのラッパーを作成します。

package forum8198945;

import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

public class XMLStreamWriterWrapper implements XMLStreamWriter {

    private XMLStreamWriter xmlStreamWriter;

    public XMLStreamWriterWrapper(XMLStreamWriter xmlStreamWriter) {
        this.xmlStreamWriter = xmlStreamWriter;
    }

    public void writeStartElement(String localName) throws XMLStreamException {
        xmlStreamWriter.writeStartElement(localName);
    }

    public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
        xmlStreamWriter.writeStartElement(namespaceURI, localName);
    }

    public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
        xmlStreamWriter.writeStartElement(prefix, localName, namespaceURI);
    }

    public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
        xmlStreamWriter.writeEmptyElement(namespaceURI, localName);
    }

    public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
        xmlStreamWriter.writeEmptyElement(prefix, localName, namespaceURI);
    }

    public void writeEmptyElement(String localName) throws XMLStreamException {
        xmlStreamWriter.writeEmptyElement(localName);
    }

    public void writeEndElement() throws XMLStreamException {
        xmlStreamWriter.writeEndElement();
    }

    public void writeEndDocument() throws XMLStreamException {
        xmlStreamWriter.writeEndDocument();
    }

    public void close() throws XMLStreamException {
        xmlStreamWriter.close();
    }

    public void flush() throws XMLStreamException {
        xmlStreamWriter.flush();
    }

    public void writeAttribute(String localName, String value) throws XMLStreamException {
        xmlStreamWriter.writeAttribute(localName, value);
    }

    public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException {
        if("http://www.w3.org/2001/XMLSchema-instance".equals(namespaceURI)) {
            int colonIndex = value.indexOf(':');
            if(colonIndex > -1) {
                value = value.substring(colonIndex + 1);
            }
            xmlStreamWriter.writeAttribute(localName, value);
        } else {
            xmlStreamWriter.writeAttribute(prefix, namespaceURI, localName, value);
        }
    }

    public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
        if("http://www.w3.org/2001/XMLSchema-instance".equals(namespaceURI)) {
            int colonIndex = value.indexOf(':');
            if(colonIndex > -1) {
                value = value.substring(colonIndex + 1);
            }
            xmlStreamWriter.writeAttribute(localName, value);
        } else {
            xmlStreamWriter.writeAttribute(namespaceURI, localName, value);
        }
    }

    public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
        if(!"http://www.w3.org/2001/XMLSchema-instance".equals(namespaceURI) && !"http://www.w3.org/2001/XMLSchema".equals(namespaceURI)) {
            xmlStreamWriter.writeNamespace(prefix, namespaceURI);
        }
    }

    public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {
        if(!"http://www.w3.org/2001/XMLSchema-instance".equals(namespaceURI)) {
            xmlStreamWriter.writeDefaultNamespace(namespaceURI);
        }
    }

    public void writeComment(String data) throws XMLStreamException {
        // TODO Auto-generated method stub
    }

    public void writeProcessingInstruction(String target) throws XMLStreamException {
        // TODO Auto-generated method stub
    }

    public void writeProcessingInstruction(String target, String data) throws XMLStreamException {
        // TODO Auto-generated method stub
    }

    public void writeCData(String data) throws XMLStreamException {
        // TODO Auto-generated method stub
    }

    public void writeDTD(String dtd) throws XMLStreamException {
        // TODO Auto-generated method stub
    }

    public void writeEntityRef(String name) throws XMLStreamException {
        // TODO Auto-generated method stub
    }

    public void writeStartDocument() throws XMLStreamException {
        xmlStreamWriter.writeStartDocument();
    }

    public void writeStartDocument(String version) throws XMLStreamException {
        xmlStreamWriter.writeStartDocument(version);
    }

    public void writeStartDocument(String encoding, String version) throws XMLStreamException {
        xmlStreamWriter.writeStartDocument(encoding, version);
    }

    public void writeCharacters(String text) throws XMLStreamException {
        xmlStreamWriter.writeCharacters(text);
    }

    public void writeCharacters(char[] text, int start, int len) throws XMLStreamException {
        xmlStreamWriter.writeCharacters(text, start, len);
    }

    public String getPrefix(String uri) throws XMLStreamException {
        return xmlStreamWriter.getPrefix(uri);
    }

    public void setPrefix(String prefix, String uri) throws XMLStreamException {
        xmlStreamWriter.setPrefix(prefix, uri);
    }

    public void setDefaultNamespace(String uri) throws XMLStreamException {
        xmlStreamWriter.setDefaultNamespace(uri);
    }

    public void setNamespaceContext(NamespaceContext context) throws XMLStreamException {
        xmlStreamWriter.setNamespaceContext(context);
    }

    public NamespaceContext getNamespaceContext() {
        return xmlStreamWriter.getNamespaceContext();
    }

    public Object getProperty(String name) throws IllegalArgumentException {
        return xmlStreamWriter.getProperty(name);
    }

}

XMLStreamReaderWrapper

ラッパーを作成する必要があります。これXMLStreamReaderにより、で取り除いたすべてのものが追加されXMLStreamWriterます。XMLStreamReader拡張できるので、これは簡単StreamReaderDelegateです。

package forum8198945;

import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;

public class XMLStreamReaderWrapper extends StreamReaderDelegate {

    public XMLStreamReaderWrapper(XMLStreamReader xmlStreamReader) {
        super(xmlStreamReader);
    }

    @Override
    public String getAttributeNamespace(int index) {
        String attributeName = getAttributeLocalName(index);
        if("type".equals(attributeName) || "nil".equals(attributeName)) {
            return "http://www.w3.org/2001/XMLSchema-instance";
        }
        return super.getAttributeNamespace(index);
    }


}

デモ

以下は、すべてがどのように組み合わされるかを示しています。

package forum8198945;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Date;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        Customer customer = new Customer();
        customer.setName("Alex Dean");
        customer.setCustomerReference(null);
        customer.setQuantity(1);
        customer.setCreatedAt(new Date());

        StringWriter stringWriter = new StringWriter();
        XMLOutputFactory xof = XMLOutputFactory.newFactory();
        XMLStreamWriter xsw = xof.createXMLStreamWriter(stringWriter);
        xsw = new XMLStreamWriterWrapper(xsw);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.marshal(customer, xsw);

        String xml = stringWriter.toString();
        System.out.println(xml);

        XMLInputFactory xif = XMLInputFactory.newFactory();
        xif.createXMLStreamReader(new StringReader(xml));

        printValue(customer.getName());
        printValue(customer.getCustomerReference());
        printValue(customer.getQuantity());
        printValue(customer.getCreatedAt());
    }

    private static void printValue(Object value) {
        System.out.print(value);
        System.out.print(" ");
        if(null != value) {
            System.out.print(value.getClass());
        }
        System.out.println();
    }

}

出力

<?xml version="1.0"?><customer><createdAt type="dateTime">2011-11-25T13:36:49.095</createdAt><customerReference nil="true"></customerReference><name type="string">Alex Dean</name><quantity type="int">1</quantity></customer>
Alex Dean class java.lang.String
null 
1 class java.lang.Integer
Fri Nov 25 13:36:49 EST 2011 class java.util.Date

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

名前空間でデータ型を直接定義する方法

分類Dev

同じ定義で異なる名前空間のデータ型を渡す

分類Dev

PowerShellで名前空間マネージャーのデフォルトの名前空間を設定する

分類Dev

Pythonで同じ品種名の「class」と「def」の間で属性値を取得および設定する方法

分類Dev

Swiftでさまざまなデータ型を取得および設定する

分類Dev

名前空間が設定されている要素の属性を取得する方法

分類Dev

シリアル化の強化-異なる名前空間の単一データ型のロードおよび保存メソッドを使用

分類Dev

Thymeleaf:名前空間で属性を設定する

分類Dev

React withTypescriptで非宣言型名前空間を許可する方法

分類Dev

名前空間の属性に新しい値を設定する

分類Dev

Angular Dynamic Components:データを設定および取得する方法

分類Dev

Javacode Androidでxml名前空間値を設定する方法

分類Dev

OpenLayersでレイヤーのカスタム属性を設定および取得する方法

分類Dev

PHPでXMLタグの名前空間を設定します

分類Dev

名前空間全体のclojureおよびunbound変数で前方宣言を使用する方法

分類Dev

JAXB:xmlns:xsiの名前空間定義の繰り返しを回避する方法

分類Dev

属性セットが属性に必要な名前空間を設定できるようにする

分類Dev

XmlTextWriterで複数の名前空間を設定する

分類Dev

.NETWCFでSOAPメッセージヘッダー要素の名前空間を明示的に設定する方法

分類Dev

サービス参照の名前空間を手動で設定する

分類Dev

座標および非空間的特徴に関する地理空間データのクラスタリング

分類Dev

古い名前空間と新しい名前空間でavroデータを使用する方法

分類Dev

JAXBを使用して名前空間でXMLを解析する方法

分類Dev

C#でユーザー定義の名前空間を作成する方法

分類Dev

マーシャリング時にJAXBの要素に名前空間属性を追加するにはどうすればよいですか?

分類Dev

XPath:クエリのデフォルトの名前空間を設定する方法はありますか?

分類Dev

Kubernetesでデフォルトの名前空間を設定できますか?

分類Dev

別々のファイルで宣言および定義された2つのクラスにC ++で同じ名前空間を使用する

分類Dev

名前空間javascriptでobjコンストラクターを定義する最良の方法

Related 関連記事

  1. 1

    名前空間でデータ型を直接定義する方法

  2. 2

    同じ定義で異なる名前空間のデータ型を渡す

  3. 3

    PowerShellで名前空間マネージャーのデフォルトの名前空間を設定する

  4. 4

    Pythonで同じ品種名の「class」と「def」の間で属性値を取得および設定する方法

  5. 5

    Swiftでさまざまなデータ型を取得および設定する

  6. 6

    名前空間が設定されている要素の属性を取得する方法

  7. 7

    シリアル化の強化-異なる名前空間の単一データ型のロードおよび保存メソッドを使用

  8. 8

    Thymeleaf:名前空間で属性を設定する

  9. 9

    React withTypescriptで非宣言型名前空間を許可する方法

  10. 10

    名前空間の属性に新しい値を設定する

  11. 11

    Angular Dynamic Components:データを設定および取得する方法

  12. 12

    Javacode Androidでxml名前空間値を設定する方法

  13. 13

    OpenLayersでレイヤーのカスタム属性を設定および取得する方法

  14. 14

    PHPでXMLタグの名前空間を設定します

  15. 15

    名前空間全体のclojureおよびunbound変数で前方宣言を使用する方法

  16. 16

    JAXB:xmlns:xsiの名前空間定義の繰り返しを回避する方法

  17. 17

    属性セットが属性に必要な名前空間を設定できるようにする

  18. 18

    XmlTextWriterで複数の名前空間を設定する

  19. 19

    .NETWCFでSOAPメッセージヘッダー要素の名前空間を明示的に設定する方法

  20. 20

    サービス参照の名前空間を手動で設定する

  21. 21

    座標および非空間的特徴に関する地理空間データのクラスタリング

  22. 22

    古い名前空間と新しい名前空間でavroデータを使用する方法

  23. 23

    JAXBを使用して名前空間でXMLを解析する方法

  24. 24

    C#でユーザー定義の名前空間を作成する方法

  25. 25

    マーシャリング時にJAXBの要素に名前空間属性を追加するにはどうすればよいですか?

  26. 26

    XPath:クエリのデフォルトの名前空間を設定する方法はありますか?

  27. 27

    Kubernetesでデフォルトの名前空間を設定できますか?

  28. 28

    別々のファイルで宣言および定義された2つのクラスにC ++で同じ名前空間を使用する

  29. 29

    名前空間javascriptでobjコンストラクターを定義する最良の方法

ホットタグ

アーカイブ