There's no need for recursive calls of the Unmarshaller, and you
should not try to get chunks of XML as a String value.
Run this through xjc:
<xs:schema xmlns:xs="
http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="
http://java.sun.com/xml/ns/jaxb"
version="2.0">
<xs:element name="result" type="valueType"/>
<xs:complexType name="paramType">
<xs:sequence>
<xs:element name="param_id" type="xs:string"/>
<xs:element name="value" type="valueType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="valueType" mixed="1">
<xs:sequence>
<xs:element name="param" type="paramType"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
and use the resulting classes:
private void printParams( String indent, ValueType value ){
for( Object xobj: value.getContent() ){
if(xobj instanceof JAXBElement ){
JAXBElement<?> jobj = (JAXBElement)xobj;
String tag = jobj.getName().getLocalPart();
if( "param".equals( tag ) ){
ParamType param = (ParamType)jobj.getValue();
System.out.println( indent + "id: " + param.getParamId() );
printParams( indent + " ", param.getValue() );
} else {
throw new IllegalStateException( "???" + tag );
}
} else if(xobj instanceof String ){
String sobj = (String)xobj;
if( ! sobj.matches( "\\s*" ) ){
System.out.println( indent + "value: " + sobj );
}
} else {
System.out.println( indent + xobj + " " + xobj.getClass() );
}
}
}
void unmarshal() throws Exception {
JAXBContext jc = JAXBContext.newInstance( PACKAGE );
Unmarshaller m = jc.createUnmarshaller();
JAXBElement<ValueType> obj = null;
try {
obj = (JAXBElement<ValueType>)m.unmarshal( new File( XMLIN ) );
} catch( Exception e ){
e.printStackTrace();
}
ValueType val = (ValueType)obj.getValue();
printParams( "", val );
}
Please do not complain if you don't like the way unmarshalling has to
be done. This is due to the reuse of the <value> element for a single
scalar value and a list of <param> elements. This requires mixed, and
then you have to handle the cocktail. (IMHO, another design flaw by
you-know-who.)
-W
On 27 September 2011 16:23, alexis <alzrck_at_gmail.com> wrote:
> Just for testing i did this
> added a <result> tag on top and a </result> on bottom, it makes validators
> show no errors. and i wrote some basic code
>
> public class Test {
> private static org.apache.log4j.Logger log = Logger.getLogger(Test.class);
> public static void main(String[] args) {
> String a =
> "<result><param><param_id>24</param_id><value><param><param_id>1</param_id><value>3</value></param><param><param_id>6</param_id><value>7</value></param><param><param_id>7</param_id><value>7</value></param><param><param_id>8</param_id><value>10000</value></param><param><param_id>9</param_id><value>1544</value></param><param><param_id>15</param_id><value>2</value></param></value></param><param><param_id>22</param_id><value><param><param_id>1</param_id><value>1</value></param><param><param_id>3</param_id><value>3</value></param><param><param_id>5</param_id><value>1</value></param><param><param_id>6</param_id><value>1</value></param><param><param_id>9</param_id><value><param><param_id>2</param_id><value>17</value></param><param><param_id>9</param_id><value>2727</value></param><param><param_id>10</param_id><value>2727</value></param></value></param></value></param><param><param_id>25</param_id><value><param><param_id>1</param_id><value>4</value></param><param><param_id>6</param_id><value>7</value></param><param><param_id>7</param_id><value>7</value></param><param><param_id>8</param_id><value>10000</value></param><param><param_id>9</param_id><value>1544</value></param></value></param><param><param_id>23</param_id><value><param><param_id>1</param_id><value>2</value></param><param><param_id>3</param_id><value>4</value></param><param><param_id>5</param_id><value>1</value></param><param><param_id>6</param_id><value>1</value></param><param><param_id>9</param_id><value><param><param_id>2</param_id><value>17</value></param><param><param_id>9</param_id><value>2427</value></param><param><param_id>10</param_id><value>2427</value></param></value></param></value></param></result>";
>
> try {
> Result res = new Result();
> List<comp> comp = new ArrayList<comp>();
> comp co = new comp();
> co.setParam_id("id1");
> co.setValue("value1");
> comp.add(co);
> res.setParam(comp);
>
> ByteArrayOutputStream xmlOut = new ByteArrayOutputStream();
> JAXBContext context = JAXBContext.newInstance(Result.class);
> Marshaller m = context.createMarshaller();
> m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
> m.marshal(res, xmlOut);
> System.out.println(xmlOut.toString());
> } catch (Exception e) {
> System.out.println(e.getMessage());
> }
>
>
> try
> {
> ByteArrayInputStream input = new ByteArrayInputStream(a.getBytes());
> JAXBContext context = JAXBContext.newInstance(Result.class);
> Unmarshaller um = context.createUnmarshaller();
> Result cf = (Result) um.unmarshal(input);
> log.info("");
> }
> catch (Exception e)
> {
> System.out.println(e);
> }
> log.info("Hello World ... read a book");
> }
>
> @XmlAccessorType(XmlAccessType.FIELD)
> public static class comp
> {
> private String param_id;
> private String value;
> public String getParam_id() {
> return param_id;
> }
> public void setParam_id(String param_id) {
> this.param_id = param_id;
> }
> public String getValue() {
> return value;
> }
> public void setValue(String value) {
> this.value = value;
> }
> }
> @XmlRootElement
> @XmlAccessorType(XmlAccessType.FIELD)
> public static class Result
> {
> private List<comp> param;
> public List<comp> getParam() {
> return param;
> }
> public void setParam(List<comp> param) {
> this.param = param;
> }
> }
>
> when i run this i get 5 elements (looking on the unmarshall part) on the
> list inside the cf object. My question is, why at the first element of the
> List inside cf, that has this part <param_id>24</param_id> inside, value
> remains empty, and not with the string
> "<param><param_id>1</param_id><value>3</value></param><param><param_id>6</param_id><value>7</value></param><param><param_id>7</param_id><value>7</value></param><param><param_id>8</param_id><value>10000</value></param><param><param_id>9</param_id><value>1544</value></param><param><param_id>15</param_id><value>2</value></param>"
>
> Because if it were the case i can match , i dont know "^<param>" in the
> string and call a new unmarshaller until i get everything i need.
>
> It's easy to see running this example and setting a breakpoint on this line
> log.info(""); below Result cf = (Result) um.unmarshal(input); debug it and
> checking the contents of cf object
>
>
> On Sep 27, 2011, at 6:16 AM, Wolfgang Laun wrote:
>
> You can use some XML validator to throw it back into their teeth ;-)
> This sort of gross deviation is detected even when you don't provide an XML
> schema.
>
> Of ourse, you can simply enclose the reeived text in some additional
> element. But what about the XML header?
>
> -W
>
>
>