Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #35149 > unrolled thread

XML

Started byEric Douglas <e.d.programmer@gmail.com>
First post2016-07-29 13:25 -0700
Last post2016-08-01 08:46 -0400
Articles 20 on this page of 37 — 5 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  XML Eric Douglas <e.d.programmer@gmail.com> - 2016-07-29 13:25 -0700
    Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-07-29 19:46 -0400
    Re: XML Roedy Green <inquiry@mindprod.com> - 2016-07-30 17:09 -0700
      Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-07-30 21:49 -0400
        Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-07-30 22:35 -0400
        Re: XML Roedy Green <inquiry@mindprod.com> - 2016-07-31 21:39 -0700
          Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-01 05:19 -0700
            Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-08-01 08:51 -0400
              Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-05 06:07 -0700
                Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-05 10:17 -0700
                Re: XML Stanimir Stamenkov <s7an10@netscape.net> - 2016-08-07 19:04 +0300
                  Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-08 05:38 -0700
                    Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-08 07:19 -0700
                    Re: XML Stanimir Stamenkov <s7an10@netscape.net> - 2016-08-09 23:57 +0300
                      Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-10 05:37 -0700
                      Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-10 10:39 -0700
                        Re: XML Stanimir Stamenkov <s7an10@netscape.net> - 2016-08-10 22:05 +0300
                          Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-10 13:29 -0700
                            Re: XML Stanimir Stamenkov <s7an10@netscape.net> - 2016-08-11 02:18 +0300
                              Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-11 05:15 -0700
                                Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-11 05:50 -0700
                              Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-11 12:24 -0700
                            Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-08-13 15:38 -0400
                              Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-16 11:49 -0700
                                Re: XML Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-08-16 15:57 -0400
                                  Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-16 13:20 -0700
                                    Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-08-16 17:04 -0400
                                      Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-08-16 21:37 -0400
                                        Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-17 05:22 -0700
                                      Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-17 05:21 -0700
                                Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-08-16 16:13 -0400
                                  Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-16 13:22 -0700
                                    Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-08-16 16:53 -0400
                                  Re: XML Eric Douglas <e.d.programmer@gmail.com> - 2016-08-16 13:32 -0700
                                    Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-08-16 16:47 -0400
                                    Re: XML Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-08-16 16:59 -0400
          Re: XML Arne Vajhøj <arne@vajhoej.dk> - 2016-08-01 08:46 -0400

Page 1 of 2  [1] 2  Next page →


#35149 — XML

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-07-29 13:25 -0700
SubjectXML
Message-ID<34f5f605-db80-441c-9730-ceecf445c1a8@googlegroups.com>
Anyone here have much experience with XML?  What method(s) do you use, and why?

I'm trying to write an in house API for developing XML code which can read and write data for my application.  I already have all the GUI but my data is currently stored in a binary format.  I want to get data into a text format for at least one utility to be maintained locally by multiple developers so we can share changes via SourceTree (https://www.atlassian.com/software/sourcetree).  I want this API to be easy to use, readable, flexible, and efficient.  Beyond this one utility we may find other practical applications.

I started research and it's a bit overwhelming, so much XML in Java.
SAX
DOM
StAX
JDOM
xerces
xpath
JAXB
JAXP
XQuery
???

[toc] | [next] | [standalone]


#35150

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-07-29 19:46 -0400
Message-ID<nngptc$18gu$1@gioia.aioe.org>
In reply to#35149
On 7/29/2016 4:25 PM, Eric Douglas wrote:
> I'm trying to write an in house API for developing XML code which can
> read and write data for my application.  I already have all the GUI
> but my data is currently stored in a binary format.  I want to get
> data into a text format for at least one utility to be maintained
> locally by multiple developers so we can share changes via SourceTree
> (https://www.atlassian.com/software/sourcetree).  I want this API to
> be easy to use, readable, flexible, and efficient.  Beyond this one
> utility we may find other practical applications.
>
> I started research and it's a bit overwhelming, so much XML in Java.
> SAX DOM StAX JDOM xerces xpath JAXB JAXP XQuery ???

For you specific problem I would be inclined to use JAXB if possible
and fall back to DOM (W3C DOM or JDOM) if not possible.

StAX seems to low level for your usage.

Arne


[toc] | [prev] | [next] | [standalone]


#35152

FromRoedy Green <inquiry@mindprod.com>
Date2016-07-30 17:09 -0700
Message-ID<t9gqpb19cdmnl2sgformolvii8pe4et688@4ax.com>
In reply to#35149
On Fri, 29 Jul 2016 13:25:38 -0700 (PDT), Eric Douglas
<e.d.programmer@gmail.com> wrote:

>Anyone here have much experience with XML?  What method(s) do you use, and =
>why?
I mainly use JAXP. This is because Amazon uses it. They give you a
descriptor of the various files you send back and forth. Java is smart
enough to turn them into code to parse them and build them.

[toc] | [prev] | [next] | [standalone]


#35153

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-07-30 21:49 -0400
Message-ID<nnjlfe$spe$1@gioia.aioe.org>
In reply to#35152
On 7/30/2016 8:09 PM, Roedy Green wrote:
> On Fri, 29 Jul 2016 13:25:38 -0700 (PDT), Eric Douglas
> <e.d.programmer@gmail.com> wrote:
>> Anyone here have much experience with XML?  What method(s) do you use, and =
>> why?
> I mainly use JAXP. This is because Amazon uses it. They give you a
> descriptor of the various files you send back and forth. Java is smart
> enough to turn them into code to parse them and build them.

That sounds like JAXB not JAXP!

Arne

[toc] | [prev] | [next] | [standalone]


#35155

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-07-30 22:35 -0400
Message-ID<nnjo4v$vi6$2@gioia.aioe.org>
In reply to#35153
On 7/30/2016 9:49 PM, Arne Vajhøj wrote:
> On 7/30/2016 8:09 PM, Roedy Green wrote:
>> On Fri, 29 Jul 2016 13:25:38 -0700 (PDT), Eric Douglas
>> <e.d.programmer@gmail.com> wrote:
>>> Anyone here have much experience with XML?  What method(s) do you
>>> use, and =
>>> why?
>> I mainly use JAXP. This is because Amazon uses it. They give you a
>> descriptor of the various files you send back and forth. Java is smart
>> enough to turn them into code to parse them and build them.
>
> That sounds like JAXB not JAXP!

JAXP is an umbrella for W3C DOM + SAX + StAX.

JAXB is XML binding including the xjc utility.

Arne

[toc] | [prev] | [next] | [standalone]


#35157

FromRoedy Green <inquiry@mindprod.com>
Date2016-07-31 21:39 -0700
Message-ID<kvjtpblrc7j5i3u62ee6japlm9481ajavq@4ax.com>
In reply to#35153
On Sat, 30 Jul 2016 21:49:38 -0400, Arne Vajhøj <arne@vajhoej.dk>
wrote:

>That sounds like JAXB not JAXP!

Both Java and Amazon refer to it only as JAX.
"%JDK64\bin\wsimport.exe" converts the description to Java code
The description lives in
http://ecs.amazonaws.com/AWSECommerceService/2013-08-01/AWSECommerceService.wsdl

What marker would make it absolutely certain I have either JAXP or
JAXB?

For simple jobs, you can use an XML editor called
Stylus Studio. It will generate an XSD which you can tweak.

[toc] | [prev] | [next] | [standalone]


#35158

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-08-01 05:19 -0700
Message-ID<0176078c-ab98-4e66-ba3e-b14ee88b58e0@googlegroups.com>
In reply to#35157
On Monday, August 1, 2016 at 12:40:07 AM UTC-4, Roedy Green wrote:
> Both Java and Amazon refer to it only as JAX.
> "%JDK64\bin\wsimport.exe" converts the description to Java code
> The description lives in
> http://ecs.amazonaws.com/AWSECommerceService/2013-08-01/AWSECommerceService.wsdl
> 
> What marker would make it absolutely certain I have either JAXP or
> JAXB?
> 
> For simple jobs, you can use an XML editor called
> Stylus Studio. It will generate an XSD which you can tweak.

I don't see any mention of jax in that wsdl.  It does mention soap, which seems to be the most popular method of accessing xml with a web service, which I may need eventually but I don't believe I need for my data at this time.

I have wondered if I should need a full on JAXB (create a Java class for each data set?) or if an XSD for each data set would suffice.  I just need some concept of record/field/field type, as in record tags all containing the same fields and having a key property, field tags containing field names and having a type enforcement (allows character, numeric only).

[toc] | [prev] | [next] | [standalone]


#35160

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-08-01 08:51 -0400
Message-ID<nnngk6$603$1@gioia.aioe.org>
In reply to#35158
On 8/1/2016 8:19 AM, Eric Douglas wrote:
> On Monday, August 1, 2016 at 12:40:07 AM UTC-4, Roedy Green wrote:
>> Both Java and Amazon refer to it only as JAX.
>> "%JDK64\bin\wsimport.exe" converts the description to Java code The
>> description lives in
>> http://ecs.amazonaws.com/AWSECommerceService/2013-08-01/AWSECommerceService.wsdl

> I don't see any mention of jax in that wsdl.

WSDL is a general standard and not tied to Java.

JAX is a common prefix for all Java XML standards. The specific one
relevant for WSDL and SOAP is JAX-WS.

So obvious JAX-WS can refer to WSDL but WSDL can not refer to JAX-WS.

>                                                It does mention soap,
> which seems to be the most popular method of accessing xml with a web
> service, which I may need eventually but I don't believe I need for
> my data at this time.

RESTFul web services (JAX-RS in Java) may have overtaken the most
popular position from SOAP web services (JAX-WS).

But for specific scenarios it depends a lot on whether you are
integrating with IBM/Oracle/MS ESB or exposing functionality to
smartphone apps and browsers.

:-)

> I have wondered if I should need a full on JAXB (create a Java class
> for each data set?) or if an XSD for each data set would suffice.  I
> just need some concept of record/field/field type, as in record tags
> all containing the same fields and having a key property, field tags
> containing field names and having a type enforcement (allows
> character, numeric only).

Actually JAXB and XSD works great together.

Create your XSD's. Use the XJC tool to generate Java classes
with JAXB annotations and you are up and running with JAXB.

Arne

[toc] | [prev] | [next] | [standalone]


#35205

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-08-05 06:07 -0700
Message-ID<d7e3e460-1025-4670-b425-672f4196d9e2@googlegroups.com>
In reply to#35160
So I'm testing out a generic data file XML and here's what I've got so far.

public class DataRecord {

}

import java.util.ArrayList;
import java.util.List;

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

@XmlRootElement(name = "DataFile")
public class DataFile<E> {
     List<DataRecord> records;
     
     public List<DataRecord> getRecords() {
          return records;
     }
     
     @XmlElement(name = "DataRecord")
     public void setRecords(List<DataRecord> newRecords) {
          records = newRecords;
     }
     
     public void add(DataRecord newRec) {
          if (records == null) {
               records = new ArrayList<>();
          }
          records.add(newRec);
     }
}


import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSeeAlso;

@XmlSeeAlso(DataFile.class)
public class Customer extends DataRecord {

     String name;
     int age;
     int id;

     public String getName() {
          return name;
     }

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

     public int getAge() {
          return age;
     }

     @XmlElement
     public void setAge(final int age) {
          this.age = age;
     }

     public int getId() {
          return id;
     }

     @XmlAttribute
     public void setId(final int id) {
          this.id = id;
     }

}

Then my test class:

import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class JAXBtoXML {

     public static void main(final String[] args) {

          final Customer customer = new Customer();
          customer.setId(100);
          customer.setName("John Smith");
          customer.setAge(29);

          final Customer customer2 = new Customer();
          customer2.setId(101);
          customer2.setName("Jane Doe");
          customer2.setAge(30);

          try {

               final File file = new File("C:\\test\\customer_jaxb.xml");
               final JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
               final Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

               // output pretty printed
               jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

               DataFile<Customer> customerList = new DataFile();
               customerList.add(customer);
               customerList.add(customer2);
               jaxbMarshaller.marshal(customerList, System.out);
               jaxbMarshaller.marshal(customerList, file);

          } catch (final JAXBException e) {
               e.printStackTrace();
          }

     }
}

My Output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DataFile>
    <DataRecord xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="customer" id="100">
        <age>29</age>
        <name>John Smith</name>
    </DataRecord>
    <DataRecord xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="customer" id="101">
        <age>30</age>
        <name>Jane Doe</name>
    </DataRecord>
</DataFile>

Do I want that whole xmlns on every record or what next to get rid of it?

[toc] | [prev] | [next] | [standalone]


#35211

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-08-05 10:17 -0700
Message-ID<ba853c96-3c63-46a6-86db-09e69bc1bb57@googlegroups.com>
In reply to#35205
On Friday, August 5, 2016 at 9:08:02 AM UTC-4, Eric Douglas wrote:
> My Output:
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <DataFile>
>     <DataRecord xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="customer" id="100">
>         <age>29</age>
>         <name>John Smith</name>
>     </DataRecord>
>     <DataRecord xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="customer" id="101">
>         <age>30</age>
>         <name>Jane Doe</name>
>     </DataRecord>
> </DataFile>
> 
> Do I want that whole xmlns on every record or what next to get rid of it?

I can't figure out if that whole xmlns:xsi piece is a necessary evil of JAXB I would think shouldn't be required of an xml file that's only ever stored and used locally or if I'm missing something to clear it, but I did find this one statement which can move it up a level.

jaxbMarshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "");

> <DataFile>
>     <DataRecord xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="customer" id="100">

becomes
<DataFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="">
     <DataRecord xsi:type="customer" id="100">

[toc] | [prev] | [next] | [standalone]


#35224

FromStanimir Stamenkov <s7an10@netscape.net>
Date2016-08-07 19:04 +0300
Message-ID<no7m5v$f24$1@dont-email.me>
In reply to#35205
Fri, 5 Aug 2016 06:07:37 -0700 (PDT), Eric Douglas:

> @XmlSeeAlso(DataFile.class)
> public class Customer extends DataRecord {
>[...]
>
> My Output:
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <DataFile>
>      <DataRecord xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="customer" id="100">
>          <age>29</age>
>          <name>John Smith</name>
>      </DataRecord>
>      <DataRecord xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="customer" id="101">
>          <age>30</age>
>          <name>Jane Doe</name>
>      </DataRecord>
> </DataFile>
>
> Do I want that whole xmlns on every record or what next to get rid of it?

That's because your Customer class is not annotated as/bound to a 
top-level XML element type (it really helps understanding the XML 
Schema model in this context).  Try using @XmlRootElement on it:

@XmlRootElement
public class Customer extends DataRecord {

I think @XmlSeeAlso(DataFile.class) on the Customer class is 
superfluous.  In certain situations you may need it the other way 
around:

@XmlSeeAlso(Customer.class)
public class DataRecord {

-- 
Stanimir

[toc] | [prev] | [next] | [standalone]


#35229

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-08-08 05:38 -0700
Message-ID<487a50aa-8e4b-460a-9824-bd23c26d4c02@googlegroups.com>
In reply to#35224
On Sunday, August 7, 2016 at 12:04:28 PM UTC-4, Stanimir Stamenkov wrote:
> That's because your Customer class is not annotated as/bound to a 
> top-level XML element type (it really helps understanding the XML 
> Schema model in this context).  Try using @XmlRootElement on it:
> 
> @XmlRootElement
> public class Customer extends DataRecord {
> 
> I think @XmlSeeAlso(DataFile.class) on the Customer class is 
> superfluous.  In certain situations you may need it the other way 
> around:
> 
> @XmlSeeAlso(Customer.class)
> public class DataRecord {

There are a number of confusing things in the JAXB, those are a couple of them.

Does it make any sense to put @XmlRootElement on Customer?  It appears to work the same with or without it, and when marshalled to the file it will never be the root.  DataFile is the root, that is it's purpose.  The only purpose of DataRecord is to be something generic the DataFile can store as a collection.  Customer, and other classes, extend the DataRecord to define a single record.  One file starts with none of these, typically has many Customers (or items, orders, etc).

Does it make sense to use the @XmlSeeAlso?  If I put the XmlSeeAlso on the Customer to point to the DataFile I can just pass the Customer class to the JAXBContext.newInstance, which can accept multiple classes, and gets the same output if I add the DataFile class there instead.  Perhaps this tag doesn't make sense in either direction at this level, but to cascade further down such as storing a collection of something ie shipping addresses within each customer?

Is every XML file supposed to have that xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" at least on the root node?  I tried what methods I could find and couldn't get it to go away, or write a different value.  That looks like a useful url but seems like a waste of space to write it to every file.

[toc] | [prev] | [next] | [standalone]


#35230

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-08-08 07:19 -0700
Message-ID<8cc2cd09-641c-4a3b-860e-588a5f28ec93@googlegroups.com>
In reply to#35229
On Monday, August 8, 2016 at 8:38:32 AM UTC-4, Eric Douglas wrote:
> There are a number of confusing things in the JAXB, those are a couple of them.

Still experimenting, some more things don't make sense.

I add fields to the Customer class with default getters and setters and it makes them fields as soon as they have a value.  I can put @XmlAttribute above the field declaration and it converts to an attribute tag, but it only accepts @XmlElement on the setter method and it doesn't appear to change the XML any.

@XmlElement(required=true) doesn't seem to affect anything.  It allows to marshall/unmarshall with no value and leaves out the tag.  This doesn't work without creating a schema file?  It appears I need a schema now for each DataRecord type class to define validation such as required fields, min/max field length, etc.

[toc] | [prev] | [next] | [standalone]


#35238

FromStanimir Stamenkov <s7an10@netscape.net>
Date2016-08-09 23:57 +0300
Message-ID<nodg3g$elh$1@dont-email.me>
In reply to#35229
Mon, 8 Aug 2016 05:38:22 -0700 (PDT), Eric Douglas:
> On Sunday, August 7, 2016 at 12:04:28 PM UTC-4, Stanimir Stamenkov 
> wrote:
>
>> That's because your Customer class is not annotated as/bound to a 
>> top-level XML element type (it really helps understanding the XML 
>> Schema model in this context). Try using @XmlRootElement on it:
>>
>> @XmlRootElement
>> public class Customer extends DataRecord {
>>
>> I think @XmlSeeAlso(DataFile.class) on the Customer class is 
>> superfluous. In certain situations you may need it the other way 
>> around:
>>
>> @XmlSeeAlso(Customer.class)
>> public class DataRecord { 
>
> There are a number of confusing things in the JAXB, those are a 
> couple of them.
>
> Does it make any sense to put @XmlRootElement on Customer?

That what my remark about understanding the XML Schema model was. 
The @XmlRootElement declares a top-level element type which might be 
used as document root element, but might appear as a child in 
certain content models as well.  Because you've used this DataRecord 
abstraction you need to have top-level element types if you want 
different elements to appear in a List<DataRecord>.

> It appears to work the same with or without it, and when 
> marshalled to the file it will never be the root. DataFile is the 
> root, that is it's purpose. The only purpose of DataRecord is to 
> be something generic the DataFile can store as a collection. 
> Customer, and other classes, extend the DataRecord to define a 
> single record. One file starts with none of these, typically has 
> many Customers (or items, orders, etc).
>
> Does it make sense to use the @XmlSeeAlso?

I've finally tried the whole of your example and discovered more 
discrepancies – see my reworked example at the end.

> If I put the XmlSeeAlso on the Customer to point to the DataFile I 
> can just pass the Customer class to the JAXBContext.newInstance, 
> which can accept multiple classes, and gets the same output if I 
> add the DataFile class there instead. Perhaps this tag doesn't 
> make sense in either direction at this level, but to cascade 
> further down such as storing a collection of something ie shipping 
> addresses within each customer?
>
> Is every XML file supposed to have that 
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" at least on 
> the root node? I tried what methods I could find and couldn't get 
> it to go away, or write a different value. That looks like a 
> useful url but seems like a waste of space to write it to every file.

Try my example (single "JAXBtoXML.java" file):

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlValue;

@XmlRootElement(name = "DataRecord")
@XmlSeeAlso(Customer.class)
class DataRecord {

     @XmlValue
     String text;

}

@XmlRootElement(name = "DataFile")
class DataFile<E> {

     List<DataRecord> records;

     public List<DataRecord> getRecords() {
         return records;
     }

     @XmlElementRef
     public void setRecords(List<DataRecord> newRecords) {
         records = newRecords;
     }

     public void add(DataRecord newRec) {
         if (records == null) {
             records = new ArrayList<>();
         }
         records.add(newRec);
     }
}

@XmlRootElement(name = "Customer")
class Customer extends DataRecord {

     String name;
     int age;
     int id;

     public String getName() {
         return name;
     }

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

     public int getAge() {
         return age;
     }

     @XmlElement
     public void setAge(final int age) {
         this.age = age;
     }

     public int getId() {
         return id;
     }

     @XmlAttribute
     public void setId(final int id) {
         this.id = id;
     }

}

public class JAXBtoXML {

     public static void main(final String[] args) throws Exception {

         final Customer customer = new Customer();
         customer.setId(100);
         customer.setName("John Smith");
         customer.setAge(29);

         final Customer customer2 = new Customer();
         customer2.setId(101);
         customer2.setName("Jane Doe");
         customer2.setAge(30);

         final DataRecord generic = new DataRecord();
         generic.text = "Eric";

         final JAXBContext jaxbContext = JAXBContext.newInstance(DataFile.class);
         final Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

         // output pretty printed
         jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

         DataFile<Customer> customerList = new DataFile();
         customerList.add(customer);
         customerList.add(customer2);
         customerList.add(generic);
         jaxbMarshaller.marshal(customerList, System.out);

     }
}

This produces the following output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DataFile>
     <Customer id="100">
         <age>29</age>
         <name>John Smith</name>
     </Customer>
     <Customer id="101">
         <age>30</age>
         <name>Jane Doe</name>
     </Customer>
     <DataRecord>Eric</DataRecord>
</DataFile>

See if that suits you.

-- 
Stanimir

[toc] | [prev] | [next] | [standalone]


#35242

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-08-10 05:37 -0700
Message-ID<cea9b34a-676b-47c2-a969-13277543a10a@googlegroups.com>
In reply to#35238
On Tuesday, August 9, 2016 at 4:57:31 PM UTC-4, Stanimir Stamenkov wrote:
> That what my remark about understanding the XML Schema model was. 
> The @XmlRootElement declares a top-level element type which might be 
> used as document root element, but might appear as a child in 
> certain content models as well.  Because you've used this DataRecord 
> abstraction you need to have top-level element types if you want 
> different elements to appear in a List<DataRecord>.

I think I get that, everything should be considered a root element if it's not explicitly defined to be a sub-element even if the API model is designed to never use that class as a root.

> > Does it make sense to use the @XmlSeeAlso?
> 
> I've finally tried the whole of your example and discovered more 
> discrepancies – see my reworked example at the end.

This looks like just adding a couple things that don't make sense.  DataRecord shouldn't be declared as a root because it should never be stored in a DataFile.  It's just an abstract interface for Customer and other specific record definitions to use to add a list of themselves to a DataFile.  The SeeAlso for DataFile to refer to Customer also doesn't make sense because there would be many element types that extend DataRecord so that would be a long list of SeeAlso to maintain.

The DataFile class is designed to generate/maintain one File.  This file contains many level one DataRecord type nodes.  Each DataRecord has a type which points to a more specific record definition class.  I got a good working concept of putting in records with fields and generating the file.  Now I'm trying to figure out how to retrieve specific records.  While not sure if the JAXB really needs the schemas I did write some XSD files.  They validate the elements, and it appears they can do some other things that would be useful to this application I'm still trying to figure out.

So I got rid of the SeeAlso in favor of the class array and built the file marshalling right into the DataFile, so here's what that looks like.


import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.SAXException;

@XmlRootElement(name = "DataFile")
public class DataFile<E extends DataRecord> {

     List<E> records;

     public List<E> getRecords() {
          return records;
     }
     
     public int getRecordCount() {
          if (records == null) {
               return 0;
          }
          return records.size();
     }

     @XmlElement(name = "DataRecord")
     public void setRecords(List<E> newRecords) {
          records = newRecords;
     }

     public void add(E newRec) {
          if (records == null) {
               records = new ArrayList<>();
          }
          records.add(newRec);
     }

     public void marshallXml(final String fileName) {
          try {
               final File file = new File(fileName);
               ArrayList<Class> jClasses = new ArrayList();
               jClasses.add(DataFile.class);
               final List<E> recs = getRecords();
               Schema schema = null;
               if (recs != null && recs.size() > 0) {
                    Class fileClass = recs.get(0).getClass();
                    jClasses.add(fileClass);
                    SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
                    URL schemaURL = DataFile.class.getResource("/stylesheets/" + fileClass.getSimpleName() + ".xsd");
                    if (schemaURL != null) {
                         schema = sf.newSchema(schemaURL);
                    }
               }
               final JAXBContext jaxbContext = JAXBContext.newInstance(jClasses.toArray(new Class[0]));
               final Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

               // output pretty printed
               jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
               jaxbMarshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "");
               if (schema != null) {
                    jaxbMarshaller.setSchema(schema);
               }
               jaxbMarshaller.setEventHandler(new MyValidationEventHandler());
               // for debugging only
               jaxbMarshaller.marshal(this, System.out);
               jaxbMarshaller.marshal(this, file);
          } catch (final JAXBException e) {
               e.printStackTrace();
          } catch (SAXException e) {
               e.printStackTrace();
          }
     }

     public DataFile<E> unmarshallXml(final Class recordClass, final String fileName) {
          DataFile data = null;
          try {
               final File file = new File(fileName);
               ArrayList<Class> jClasses = new ArrayList();
               jClasses.add(DataFile.class);
               jClasses.add(recordClass);
               final JAXBContext jaxbContext = JAXBContext.newInstance(jClasses.toArray(new Class[0]));

               final Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
               data = (DataFile) jaxbUnmarshaller.unmarshal(file);
          } catch (final JAXBException e) {
               e.printStackTrace();
          }
          return data;
     }

     public class MyValidationEventHandler implements ValidationEventHandler {
          public boolean handleEvent(ValidationEvent event) {
               System.out.println("\nEVENT");
               System.out.println("SEVERITY:  " + event.getSeverity());
               System.out.println("MESSAGE:  " + event.getMessage());
               System.out.println("LINKED EXCEPTION:  " + event.getLinkedException());
               System.out.println("LOCATOR");
               System.out.println("    LINE NUMBER:  " + event.getLocator().getLineNumber());
               System.out.println("    COLUMN NUMBER:  " + event.getLocator().getColumnNumber());
               System.out.println("    OFFSET:  " + event.getLocator().getOffset());
               System.out.println("    OBJECT:  " + event.getLocator().getObject());
               System.out.println("    NODE:  " + event.getLocator().getNode());
               System.out.println("    URL:  " + event.getLocator().getURL());
               return true;
          }
     }
}

and here's a sample of one of the XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
	<xs:element name="DataFile">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="DataRecord" type="rmfih" maxOccurs="unbounded"></xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:complexType name="rmfih">
		<xs:all>
			<xs:element name="FILENAME" type="xs:string"></xs:element>
            <xs:element name="FILEDESC" type="xs:string"></xs:element>
            <xs:element name="NORMALIZED" type="xs:boolean"></xs:element>
            <xs:element name="FILETYPE">
            	<xs:simpleType>
            		<xs:restriction base="xs:string">
            			<xs:maxLength value="25"></xs:maxLength>
            			<xs:whiteSpace value="collapse"></xs:whiteSpace>
            		</xs:restriction>
            	</xs:simpleType>
            </xs:element>
		</xs:all>
</xs:attribute>
	</xs:complexType>
</xs:schema>

I'm not sure what whiteSpace collapse is for, it doesn't appear to do anything.  Now I'm trying to figure out how to define key fields that make these records unique, and how to code the interface to read specific records and fields out of the file.

[toc] | [prev] | [next] | [standalone]


#35248

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-08-10 10:39 -0700
Message-ID<de36e9b4-44de-44ba-835d-80e9dc80fa90@googlegroups.com>
In reply to#35238
On Tuesday, August 9, 2016 at 4:57:31 PM UTC-4, Stanimir Stamenkov wrote:
> @XmlRootElement(name = "DataRecord")
> @XmlSeeAlso(Customer.class)
> class DataRecord {

I left the tags off the DataRecord and made it abstract, still works fine.

I tried just making DataRecord an interface, which is technically what it should be, and it threw an error on the JAXBContext.newInstance().
"DataRecord is an interface, and JAXB can't handle interfaces."

[toc] | [prev] | [next] | [standalone]


#35249

FromStanimir Stamenkov <s7an10@netscape.net>
Date2016-08-10 22:05 +0300
Message-ID<nofttr$u80$1@dont-email.me>
In reply to#35248
Wed, 10 Aug 2016 10:39:27 -0700 (PDT), Eric Douglas:
> On Tuesday, August 9, 2016 at 4:57:31 PM UTC-4, Stanimir Stamenkov 
> wrote:
>> @XmlRootElement(name = "DataRecord")
>> @XmlSeeAlso(Customer.class)
>> class DataRecord {
> I left the tags off the DataRecord and made it abstract, still 
> works fine.
>
> I tried just making DataRecord an interface, which is technically 
> what it should be, and it threw an error on the 
> JAXBContext.newInstance().
> "DataRecord is an interface, and JAXB can't handle interfaces."

It seems to me you're trying to make stuff unnecessary complicated. 
I'm not really sure why you need the base class, and you may find 
most binding frameworks have many limitations in this regard.  In 
this particular instance I'm not sure why you need (possibly) 
different derived types mapped to the same XML element type 
"DataRecord" as in:

<DataFile>
     <DataRecord>...</DataRecord>
     <DataRecord>...</DataRecord>
</DataFile>

If the two different instances of "DataRecord" map to two different 
types, then the only way to resolve this is the XML Schema 
'xsi:type' attribute – the Unmarshaller would use it to instantiate 
object of the necessary type.

As a final word, you may notice in XML an element name is generally 
used to define a single element type (if you're familiar with the 
XML DTD).  It is the much more complex XML Schema which allows you 
do other "fancy" stuff at the expense of added meta information to 
the instance document like 'xsi:type' attributes.  You need to 
design wisely both of the XML representation and Java classes bound 
to it.  Good luck in this effort.

-- 
Stanimir

[toc] | [prev] | [next] | [standalone]


#35250

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-08-10 13:29 -0700
Message-ID<00fae8a8-dc01-435f-9f33-e5a5055d93df@googlegroups.com>
In reply to#35249
On Wednesday, August 10, 2016 at 3:05:44 PM UTC-4, Stanimir Stamenkov wrote:
> It seems to me you're trying to make stuff unnecessary complicated. 
> I'm not really sure why you need the base class, and you may find 
> most binding frameworks have many limitations in this regard.  In 
> this particular instance I'm not sure why you need (possibly) 
> different derived types mapped to the same XML element type 
> "DataRecord" as in:
> 
> <DataFile>
>      <DataRecord>...</DataRecord>
>      <DataRecord>...</DataRecord>
> </DataFile>
> 
> If the two different instances of "DataRecord" map to two different 
> types, then the only way to resolve this is the XML Schema 
> 'xsi:type' attribute – the Unmarshaller would use it to instantiate 
> object of the necessary type.
> 
> As a final word, you may notice in XML an element name is generally 
> used to define a single element type (if you're familiar with the 
> XML DTD).  It is the much more complex XML Schema which allows you 
> do other "fancy" stuff at the expense of added meta information to 
> the instance document like 'xsi:type' attributes.  You need to 
> design wisely both of the XML representation and Java classes bound 
> to it.  Good luck in this effort.

Correct.

Each element of DataRecord has xsi:type="specificfiletype" used to generate the specific file type class instance.

I did manage to create and test a couple XSD files to marshall/unmarshall DataFiles with DataRecords in them which appear to be working fine.  This adds validation to ensure each record has the correct fields in it, the fields have the correct type of value, and each DataRecord is unique according to the main key fields.

sample:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns=""
	elementFormDefault="qualified" attributeFormDefault="unqualified">
	<xs:element name="DataFile">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="DataRecord" type="rmfid" maxOccurs="unbounded" />
			</xs:sequence>
		</xs:complexType>
		<xs:unique name="Key">
			<xs:selector xpath="DataRecord" />
			<xs:field xpath="FILENAME" />
			<xs:field xpath="SEQNUM" />
		</xs:unique>
	</xs:element>
	<xs:complexType name="rmfid">
		<xs:all>
			<xs:element name="FILENAME" type="xs:string" />
			<xs:element name="SEQNUM" type="xs:string" />
		</xs:all>
	</xs:complexType>
</xs:schema>

Now, I'm not sure the best API to manage records.  As the only method I found for storing multiple records with JAXB is a List of the DataRecord instances, how do I pass it a key value, get one or more of these record objects, update a field (or fields), and write it back out?  This RMFID.xsd maps to an RMFID Java class which gives me instances specific to this file name where I can call it's setFILENAME(), getFILENAME() methods, but I don't see an obvious way to get specific instances of the RMFID from the list aside from customizing these classes further to map out what keys I need and mapping them through the DataFile class.
I'm wondering if it makes sense to keep going down this path or try something else, like JiBX which claims to do all this marshall/unmarshall stuff plus add code to the Java classes to make everything more efficient and support XPath queries to find records?

[toc] | [prev] | [next] | [standalone]


#35251

FromStanimir Stamenkov <s7an10@netscape.net>
Date2016-08-11 02:18 +0300
Message-ID<nogcna$ibo$1@dont-email.me>
In reply to#35250
Wed, 10 Aug 2016 13:29:36 -0700 (PDT), Eric Douglas:

> I did manage to create and test a couple XSD files to 
> marshall/unmarshall DataFiles with DataRecords in them which 
> appear to be working fine...

Not sure if it could be of any help to you (I'm often using it), but 
you could look at the generated schema also:

         JAXBContext jaxbContext = ...;
         
         jaxbContext.generateSchema(new SchemaOutputResolver() {
             @Override
             public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
                 Result result = new StreamResult(System.out);
                 result.setSystemId(new java.io.File(suggestedFileName).toURI().toString());
                 return result;
             }
         });

and possibly find out if you've got your bindings as you would expect.

> Now, I'm not sure the best API to manage records. As the only 
> method I found for storing multiple records with JAXB is a List of 
> the DataRecord instances, how do I pass it a key value, get one or 
> more of these record objects, update a field (or fields), and 
> write it back out? This RMFID.xsd maps to an RMFID Java class 
> which gives me instances specific to this file name where I can 
> call it's setFILENAME(), getFILENAME() methods, but I don't see an 
> obvious way to get specific instances of the RMFID from the list 
> aside from customizing these classes further to map out what keys 
> I need and mapping them through the DataFile class.
> I'm wondering if it makes sense to keep going down this path or 
> try something else, like JiBX which claims to do all this 
> marshall/unmarshall stuff plus add code to the Java classes to 
> make everything more efficient and support XPath queries to find 
> records?

I have no experience with JiBX.  For more sophisticated needs 
there's XmlAdapter also:

http://blog.bdoughan.com/2010/07/xmladapter-jaxbs-secret-weapon.html

I guess you could have something like then:

     @XmlJavaTypeAdapter(MyIdMapAdapter.class)
     Map<Integer, DataRecord> records;

-- 
Stanimir

[toc] | [prev] | [next] | [standalone]


#35255

FromEric Douglas <e.d.programmer@gmail.com>
Date2016-08-11 05:15 -0700
Message-ID<a20d72d2-f329-4f08-a934-c5ee4f69683d@googlegroups.com>
In reply to#35251
On Wednesday, August 10, 2016 at 7:18:12 PM UTC-4, Stanimir Stamenkov wrote:
> Not sure if it could be of any help to you (I'm often using it), but 
> you could look at the generated schema also:
> and possibly find out if you've got your bindings as you would expect.

Similar, not sure exactly what the different structure does.  For my previously mentioned rmfid.xml it came up with:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema elementFormDefault="unqualified" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="rmfid" type="rmfid"/>

  <xs:complexType name="rmfid">
    <xs:complexContent>
      <xs:extension base="dataRecord">
        <xs:sequence>
          <xs:element name="FILENAME" type="xs:string" minOccurs="0"/>
          <xs:element name="SEQNUM" type="xs:string" minOccurs="0"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="dataRecord" abstract="true">
    <xs:sequence/>
  </xs:complexType>
</xs:schema>

This might in some way be better?  Of course I still have to add my custom logic to that.  The generated schema doesn't know the key fields.  In this case there are more fields, I've only defined the key so far, every record must be unique adding filename and seqnum together.  It appears I also need tags in the class to generate schema since minOccurs="0" is not right at least for these key fields, each record should have exactly 1.

> I have no experience with JiBX.  For more sophisticated needs 
> there's XmlAdapter also:
> 
> http://blog.bdoughan.com/2010/07/xmladapter-jaxbs-secret-weapon.html
> 
> I guess you could have something like then:
> 
>      @XmlJavaTypeAdapter(MyIdMapAdapter.class)
>      Map<Integer, DataRecord> records;

I'll check it out, see if it helps.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.java.programmer


csiph-web