Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #35149 > unrolled thread
| Started by | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| First post | 2016-07-29 13:25 -0700 |
| Last post | 2016-08-01 08:46 -0400 |
| Articles | 20 on this page of 37 — 5 participants |
Back to article view | Back to comp.lang.java.programmer
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 →
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-07-29 13:25 -0700 |
| Subject | XML |
| 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]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-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]
| From | Roedy Green <inquiry@mindprod.com> |
|---|---|
| Date | 2016-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]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-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]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-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]
| From | Roedy Green <inquiry@mindprod.com> |
|---|---|
| Date | 2016-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Stanimir Stamenkov <s7an10@netscape.net> |
|---|---|
| Date | 2016-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Stanimir Stamenkov <s7an10@netscape.net> |
|---|---|
| Date | 2016-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Stanimir Stamenkov <s7an10@netscape.net> |
|---|---|
| Date | 2016-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Stanimir Stamenkov <s7an10@netscape.net> |
|---|---|
| Date | 2016-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-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