开发者

Getting a XML data present in a child node as string using JAXB

开发者 https://www.devze.com 2023-03-04 16:59 出处:网络
I am using JAXB to convert the XML(Parent XML, FIXML) to String. In that XML one child node is having another XML(Child X开发者_StackOverflowML, FpML) data for which I done have schema (xsd). In the s

I am using JAXB to convert the XML(Parent XML, FIXML) to String. In that XML one child node is having another XML(Child X开发者_StackOverflowML, FpML) data for which I done have schema (xsd). In the schema for the Parent XML, the element type which has the Child XML is defined as String. I need the child XML should come as the string. Please let me know what change I have to do. I am relatively new to JAXB. Thanks in Advance..!!

Cheers, Sakthi S


UPDATE

Based on your comments:

Hi.. Thanks for your reply.. @Blaise Doughan & @CoolBeans in the above example you provide you have mentioned String Value but in my xml, instead of "String Value" there will be another XML inside it. like Richard and I need the "Richard" as string in the output. Please let me know still you want more information. Thanks.. Cheers, Sakthi. S

You can use a combination of @XmlAnyElement and a DomHandler implementation to handle this use case. For a detailed example see:

  • http://bdoughan.blogspot.com/2011/04/xmlanyelement-and-non-dom-properties.html

UPDATE #2

Based on your comments

Can you please tell me what is change need to be done in the schema to make that filed "@XmlAnyElement", since I am generating the java classes on the build time.

You can use the JAXB dom schema annotation to cause an XmlAnyElement to be generated on a property:

XJC Call

xjc -d out -b bindings.xml dom.xsd

dom.xsd

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.example.com/default"
    targetNamespace="http://www.example.com/default">

    <xs:element name="customer">
        <xs:complexType>
        <xs:sequence>
            <xs:element ref="address"/>
        </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="address">
        <xs:complexType>
        <xs:attribute name="street" type="xs:string"/>
        </xs:complexType>
    </xs:element>

</xs:schema>

bindings.xml

<jxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">

    <jxb:bindings schemaLocation="string.xsd">
            <jxb:bindings node="//xs:element[@name='customer']/xs:complexType/xs:sequence/xs:element[@ref='address']">
                <jxb:dom/>
            </jxb:bindings>
    </jxb:bindings>

</jxb:bindings>

Customer

The address property on Customer will be annotated with @XmlAnyElement:

package com.example._default;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.w3c.dom.Element;


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "address"
})
@XmlRootElement(name = "customer")
public class Customer {

    @XmlAnyElement
    protected Element address;

    public Element getAddress() {
        return address;
    }

    public void setAddress(Element value) {
        this.address = value;
    }

}

ORIGINAL ANSWER

You may be looking for the @XmlValue annotation. For example if you had the following class:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD
public class Child {

    @XmlValue
    private String value;

}

The above class would marshal to:

<child>String Value</child>

In the corresponding XML schema the type of the child element would be xs:string.

<xs:element name="child" type="xs:string"/>


I solved it for now with

@Column(name="xml")
@XmlJavaTypeAdapter(StringXmlAdapter.class)
public String getXml() {
    return this.xml;
}

..

public class StringXmlAdapter extends XmlAdapter<Object, String>
{
   private static final String XMLSTART = "<?xml version='1.0' encoding='UTF-8'?>";

    @Override
    public Object marshal(String v) throws Exception {

        return v;
    }

    @Override
    public String unmarshal(Object v) throws Exception {
        Document document = ((Node) v).getOwnerDocument();
        DOMImplementationLS domImplLS = (DOMImplementationLS) document
            .getImplementation();
        LSSerializer serializer = domImplLS.createLSSerializer();
        String str = serializer.writeToString((Node) v);
        String normalizedXml = normalizeXml(str);
        return normalizedXml;
    }

    private String normalizeXml(String xml){
        int beginIndex = xml.indexOf('>',XMLSTART.length()+1)+1;
        int endIndex = xml.lastIndexOf('<');
        return xml.substring(beginIndex, endIndex);
    }
}

The only problem is that i get

<xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">
<inner><something>lalala</something></inner></xml>

after marshalling

down't know how to erase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string"

0

精彩评论

暂无评论...
验证码 换一张
取 消