sp_makewebtask @outputfile = 'c:\temp\myxmlfile.xml',
@query = 'SELECT ( SELECT location AS loc,ChangeFreq AS changefreq,Priority AS priority from posterdata_sitemap FOR XML PATH(''url''),TYPE)',
@templatefile = 'c:\temp\template.tpl'
/*
EXEC master.dbo.sp_configure 'show advanced options', 1
RECONFIGURE
sp_configure 'Web Assistant Procedures', 1
RECONFIGURE */
Monday, February 27, 2012
Wednesday, February 22, 2012
xml file from SQL
http://blog.sqlauthority.com/2009/02/12/sql-server-simple-example-of-creating-xml-file-using-t-sql/
I always want to learn SQL Server and XML. Let us go over very simple example today about how to create XML using SQL Server.
Please also read related article here SQL SERVER – Simple Example of Reading XML File Using T-SQL.
Following is the XML which we want to create:
T-SQL Script to generate above XML:
SELECT ( SELECT 'White' AS Color1,
'Blue' AS Color2,
'Black' AS Color3,
'Light' AS 'Color4/@Special',
'Green' AS Color4,
'Red' AS Color5
FOR
XML PATH('Colors'),
TYPE
),
( SELECT 'Apple' AS Fruits1,
'Pineapple' AS Fruits2,
'Grapes' AS Fruits3,
'Melon' AS Fruits4
FOR
XML PATH('Fruits'),
TYPE
)
FOR XML PATH(''),
ROOT('SampleXML')
GO
Tuesday, February 21, 2012
SQL server - generate sitemap table
Have you ever wondered why some of your site's pages are indexed by search engines while others are not? Using a sitemap you can tell search engines exactly where to find each of your site's pages. A sitemap is a file using XML that lists URLs for a site so that the site can be more accurately crawled by search engines.
The best news is that now you can specify the sitemap in your robots.txt file and Google's Webmaster Tools, MSN Live, and Yahoo all allow you to submit a site map URL when listing your site.
Here is an example sitemap.
After adding some data your table should look similar to this with different urls of course.
Next keeping an eye on security and performance we'll create a SQL Server stored procedure called sp_mysitemap_select to query the urls from the table we just created. Be sure to assign execute permissions for this stored procedure to the sql login that your web site uses to query the database.
We are going to add a conditional statement to this stored procedure so that we can use it later on in the example to create navigation menus for the site as well. This way once we have a new page ready on the site all we have to do is add the url to the SQL table and it will be available in the navigation menu as well as the site map automatically.
Being good programmers we always test our code on the database before hooking it into a web page so manually execute the store procedure we just created in a query window
The best news is that now you can specify the sitemap in your robots.txt file and Google's Webmaster Tools, MSN Live, and Yahoo all allow you to submit a site map URL when listing your site.
Here is an example sitemap.
<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> <loc>http://www.dotnetdesignguide.com/</loc> <changefreq>daily</changefreq> <priority>0.5</priority> </url> </urlset> Unless you have a blog or CMS you have to manually update your sitemap every time you add a new page to your site. Because aspiring web developers never do anything manual we will create a dynamic sitemap using ASP.NET and SQL Server. The urls of the pages on our site will be stored in a SQL Server table and we'll create an ASP.Net page to display the XML syntax. Additionally we could take it a step further and create navigation hyperlinks for our site or even content specific landing pages using the urls from the table
Step 1. SQL Server Table and Stored Procedure
First we create a table called "mysitemap". Open SQL Server and open a new query window in your database. Cut and paste the following SQL statement below to create the table. This table will store our data about the urls on our webite that we want search engines to find. CREATE TABLE [dbo].[MySitemap]( [ID] [int] IDENTITY(1,1) NOT NULL, [Location] [varchar](200) NULL, [ChangeFreq] [varchar](20) NULL CONSTRAINT [DF_MySitemap_ChangeFreq] DEFAULT ('daily'), [Priority] [varchar](3) NULL CONSTRAINT [DF_MySitemap_Priority] DEFAULT ((0.5)), [Category] [varchar](50) NULL, CONSTRAINT [PK_MySitemap] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] |
Next keeping an eye on security and performance we'll create a SQL Server stored procedure called sp_mysitemap_select to query the urls from the table we just created. Be sure to assign execute permissions for this stored procedure to the sql login that your web site uses to query the database.
We are going to add a conditional statement to this stored procedure so that we can use it later on in the example to create navigation menus for the site as well. This way once we have a new page ready on the site all we have to do is add the url to the SQL table and it will be available in the navigation menu as well as the site map automatically.
CREATE PROCEDURE [dbo].[sp_mysitemap_select] ( @category varchar(50) ) AS if (@category is null) begin select Location, ChangeFreq, Priority from mysitemap order by Category end else begin select Location from mysitemap where Category=@category end return |
Wednesday, February 15, 2012
java - noclassdeffounderror
http://javarevisited.blogspot.com/2011/06/noclassdeffounderror-exception-in.html
Although quite wiered, but for my case, this error was removed by logging in by a different user name. might be some startup program in my user profile which was disturbing jre.
this is how it works!
Although quite wiered, but for my case, this error was removed by logging in by a different user name. might be some startup program in my user profile which was disturbing jre.
this is how it works!
Friday, February 10, 2012
com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast
for me the error was resolved by this
@XmlAnyElement(lax = true)
public List<Foo> foos;
Java - Pass by value/Pass by reference
It is quite common that fresh developer (incorrectly) state "primitives are passed by value, objects are passed by reference". The terms "pass-by-value" semantics and "pass-by-reference" semantics have very precise definitions, and they're often horribly abused when folks talk about Java.Let's correct it.
Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.Take the badSwap() method for example:
public void badSwap(int var1, int var2)
{
int temp = var1;
var1 = var2;
var2 = temp;
}
When badSwap() returns, the variables passed as arguments will still hold their original values. The method will also fail if we change the arguments type from int to Object. Now, here is where it gets tricky:
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
}
If we execute this main() method, we see the following output:
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0
The method successfully alters the value of pnt1, even though it is passed by value; however, a swap of pnt1 and pnt2 fails! When you pass pnt1 and pnt2 to the tricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies of the original references. Figure below shows two references pointing to the same object after Java passes an object to a method.
Moral: Java always pass method arguments by value not by reference. In other words, always copies of arguments are sent to methods, in case of primitives, copies of primitives and in case of objects, the copies of references.
Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.Take the badSwap() method for example:
public void badSwap(int var1, int var2)
{
int temp = var1;
var1 = var2;
var2 = temp;
}
When badSwap() returns, the variables passed as arguments will still hold their original values. The method will also fail if we change the arguments type from int to Object. Now, here is where it gets tricky:
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
}
If we execute this main() method, we see the following output:
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0
The method successfully alters the value of pnt1, even though it is passed by value; however, a swap of pnt1 and pnt2 fails! When you pass pnt1 and pnt2 to the tricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies of the original references. Figure below shows two references pointing to the same object after Java passes an object to a method.
Moral: Java always pass method arguments by value not by reference. In other words, always copies of arguments are sent to methods, in case of primitives, copies of primitives and in case of objects, the copies of references.
Thursday, February 9, 2012
@XmlTransient for handling Interfaces
I used @XmlTransient to fix the error of "Jaxb can not handle interface". I put this annotation on an the interface and it worked fine for me at least.
if you see any issue in it. please let me know.
if you see any issue in it. please let me know.
Monday, February 6, 2012
JAXB - Mapping the unmappable
http://blog.bdoughan.com/2010/07/xmladapter-jaxbs-secret-weapon.html
The XmlAdapter mechanism in JAXB ensures that there is no such thing as an unmappable class (with a little programmatic help). However there appears to be some confusion on how to use XmlAdapter, below is the general concept:
1. Identify the Unmappable Class
In this example the unmappable class is java.util.Map.
2. Create an Equivalent Class that is Mappable
Map could be represented by an object (MyMapType), that contained a list of objects with two properties: key and value (MyMapEntryType).
and
3. Create an XmlAdapter to Convert Between Unmappable and Mappable Objects
The XmlAdapter<ValueType, BoundType> class is responsible for converting between instances of the unmappable and mappable classes. Most people get confused between the value and bound types. The value type is the mappable class, and the bound type is the unmappable class.
4. Specify the XmlAdapter
The @XmlJavaTypeAdapter annotation is used to specify the use of the XmlAdapter. Below it is specified on the map field on the Foo class. Now during marshal/unmarshal operations the instance of Map is treated as an instance of MyHashMapType.
In upcoming posts I'll describe extensions in the EclipseLink JAXB (MOXy) implementation that reduce the dependency on XmlAdapter.
Further Reading
If you enjoyed this post, then you may also be interested in:
The XmlAdapter mechanism in JAXB ensures that there is no such thing as an unmappable class (with a little programmatic help). However there appears to be some confusion on how to use XmlAdapter, below is the general concept:
- Identify the unmappable class
- Create an equivalent class that is mappable
- Create an XmlAdapter to convert between unmappable and mappable objects
- Specify the XmlAdapter
1. Identify the Unmappable Class
In this example the unmappable class is java.util.Map.
2. Create an Equivalent Class that is Mappable
Map could be represented by an object (MyMapType), that contained a list of objects with two properties: key and value (MyMapEntryType).
1 2 3 4 5 6 7 8 9 | import java.util.ArrayList; import java.util.List; public class MyMapType { public List<MyMapEntryType> entry = new ArrayList<MyMapEntryType>(); } |
and
1 2 3 4 5 6 7 8 9 10 11 12 | import javax.xml.bind.annotation.XmlValue; import javax.xml.bind.annotation.XmlAttribute; public class MyMapEntryType { @XmlAttribute public Integer key; @XmlValue public String value; } |
3. Create an XmlAdapter to Convert Between Unmappable and Mappable Objects
The XmlAdapter<ValueType, BoundType> class is responsible for converting between instances of the unmappable and mappable classes. Most people get confused between the value and bound types. The value type is the mappable class, and the bound type is the unmappable class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.xml.bind.annotation.adapters.XmlAdapter; public final class MyMapAdapter extends XmlAdapter<MyMapType,Map<Integer, String>> { @Override public MyMapType marshal(Map<Integer, String> arg0) throws Exception { MyMapType myMapType = new MyMapType(); for (Entry<Integer, String> entry : arg0.entrySet()) { MyMapEntryType myMapEntryType = new MyMapEntryType(); myMapEntryType.key = entry.getKey(); myMapEntryType.value = entry.getValue(); myMapType.entry.add(myMapEntryType); } return myMapType; } @Override public Map<Integer, String> unmarshal(MyMapType arg0) throws Exception { HashMap<Integer, String> hashMap = new HashMap<Integer, String>(); for (MyMapEntryType myEntryType : arg0.entry) { hashMap.put(myEntryType.key, myEntryType.value); } return hashMap; } } |
4. Specify the XmlAdapter
The @XmlJavaTypeAdapter annotation is used to specify the use of the XmlAdapter. Below it is specified on the map field on the Foo class. Now during marshal/unmarshal operations the instance of Map is treated as an instance of MyHashMapType.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import java.util.HashMap; import java.util.Map; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlRootElement @XmlAccessorType (XmlAccessType.FIELD) public class Foo { @XmlJavaTypeAdapter (MyMapAdapter. class ) Map<Integer, String> map = new HashMap<Integer, String>(); public Map getMap() { return map; } public void setMap(Map map) { this .map = map; } } |
In upcoming posts I'll describe extensions in the EclipseLink JAXB (MOXy) implementation that reduce the dependency on XmlAdapter.
Further Reading
If you enjoyed this post, then you may also be interested in:
- JAXB and Immutable Objects
In this post an XmlAdapter is used map a domain object with a mult-argument constructor and fields marked final. This example also demonstrates how the @XmlJavaTypeAdapter annotation can be used at the type level.
- @XmlTransformation - Going Beyond XmlAdapter
In this post an EclipseLink MOXy extension (@XmlTransformation) is used instead of @XmlAdapter to provide a little more flexibility for an interesting use case.
JAX vs Extreme
http://blog.bdoughan.com/2010/10/how-does-jaxb-compare-to-xstream.html
How Does JAXB Compare to XStream?
The XStream FAQ states the following when being compared to JAXB:
Java Model
We will use the following model for this example. The classes represent customer data. The get/set methods have been omitted to save space.
Customer Data
The following instance of Customer will be marshalled to XML using both JAXB and XStream.
Marshal Code
This is the code we will use to convert the objects to XML.
XStream
The following code will be used to marshal the instance of Customer to an OutputStream. The XStream code is quite compact.
JAXB
The following code will be used to marshal the instance of Customer to an OutputStream. A couple of differences are already apparent:
Default XML Output
First we will examine the XML output produced by both XStream and JAXB if no metadata is used to customize the output.
XStream
XStream will produce the following XML. Note some of the elements are named after the fully qualified class name.
Field Access
For this example we will configure our XML binding tools to interact directly with the fields (instance variables).
XStream
Note: The JAXB Marshal code can now be simplified since we no longer need to supply the root element information:
XML Output
At this point the same XML is being produced by XStream and JAXB.
Change the Order of Elements
We will tweak the document again to make sure that when marshalling an Address object the "street" element will always appear before the "city" element.
XStream
For XStream we will need to change our marshal code. The following is based on instructions given in the XStream FAQ:
JAXB
For JAXB we can configure the ordering of elements right on the model class. We will use @XmlType to do this.
XML Output
The XML output is the same for both JAXB and XStream.
Mapping to an Attribute
Now we will look at how to tweak the XML output using the appropriate mapping metadata to produce XML attributes. As you will see the amount of configuration required is almost identical.
XStream
JAXB
XML Output
The converter can be implemented as follows:
JAXB
For JAXB we will use the @XmlAttribute and @XmlValue annotations on the PhoneNumber class.
XML Output:
The XML output is the same for both JAXB and XStream.
We will now namespace qualify the XML document.
Note: With this change I lost XML formatting, the following was produced.
The following XML was produced
JAXB is a Java binding tool. It generates Java code from a schema and you are able to transform from those classes into XML matching the processed schema and back. Note, that you cannot use your own objects, you have to use what is generated.In this post I will provide an alternative answer to that question.
Java Model
We will use the following model for this example. The classes represent customer data. The get/set methods have been omitted to save space.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package comparison; import java.util.ArrayList; import java.util.List; public class Customer { private long id; private String name; private Address address; private List<phonenumber> phoneNumbers; public Customer() { phoneNumbers = new ArrayList<PHONENUMBER>(); } } </PHONENUMBER> |
1 2 3 4 5 6 7 8 | package comparison; public class Address { private String city; private String street; } |
1 2 3 4 5 6 7 8 | package comparison; public class PhoneNumber { private String type; private String number; } |
Customer Data
The following instance of Customer will be marshalled to XML using both JAXB and XStream.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package comparison; public class Data { public static Customer CUSTOMER; static { CUSTOMER = new Customer(); CUSTOMER.setId( 123 ); CUSTOMER.setName( "Jane Doe" ); Address address = new Address(); address.setStreet( "1 A Street" ); address.setCity( "Any Town" ); CUSTOMER.setAddress(address); PhoneNumber workPhoneNumber = new PhoneNumber(); workPhoneNumber.setType( "work" ); workPhoneNumber.setNumber( "555-WORK" ); CUSTOMER.getPhoneNumbers().add(workPhoneNumber); PhoneNumber cellPhoneNumber = new PhoneNumber(); cellPhoneNumber.setType( "cell" ); cellPhoneNumber.setNumber( "555-CELL" ); CUSTOMER.getPhoneNumbers().add(cellPhoneNumber); } } |
Marshal Code
This is the code we will use to convert the objects to XML.
XStream
The following code will be used to marshal the instance of Customer to an OutputStream. The XStream code is quite compact.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package comparison.xstream; import com.thoughtworks.xstream.XStream; import static comparison.Data.CUSTOMER; public class XStreamDemo { public static void main(String[] args) { XStream xstream = new XStream(); xstream.autodetectAnnotations( true ); xstream.toXML(CUSTOMER, System.out); } } |
JAXB
The following code will be used to marshal the instance of Customer to an OutputStream. A couple of differences are already apparent:
- A JAXBContext needs to be initialized on the binding metadata before the marshal operation can occur.
- Unlike XStream JAXB does not format the XML by default, so we will enable this feature.
- With no metadata specified we need to supply JAXB with a root element name (and namespace).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package comparison.jaxb; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.Marshaller; import javax.xml.namespace.QName; import comparison.Customer; import static comparison.Data.CUSTOMER; public class JAXBDemo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Customer. class ); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true ); JAXBElement<Customer> jaxbElement = new JAXBElement<Customer>( new QName( "customer" ), Customer. class , CUSTOMER); marshaller.marshal(jaxbElement, System.out); } } |
Default XML Output
First we will examine the XML output produced by both XStream and JAXB if no metadata is used to customize the output.
XStream
XStream will produce the following XML. Note some of the elements are named after the fully qualified class name.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | < comparison.Customer > < id >123</ id > < name >Jane Doe</ name > < address > < city >Any Town</ city > < street >1 A Street</ street > </ address > < phoneNumbers > < comparison.PhoneNumber > < type >work</ type > < number >555-WORK</ number > </ comparison.PhoneNumber > < comparison.PhoneNumber > < type >cell</ type > < number >555-CELL</ number > </ comparison.PhoneNumber > </ phoneNumbers > </ comparison.Customer > |
JAXB
JAXB produces the following XML. The representation is straight forward and more compact than the XStream representation.
JAXB produces the following XML. The representation is straight forward and more compact than the XStream representation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | < customer > < id >123</ id > < address > < city >Any Town</ city > < street >1 A Street</ street > </ address > < name >Jane Doe</ name > < phoneNumbers > < number >555-WORK</ number > < type >work</ type > </ phoneNumbers > < phoneNumbers > < number >555-CELL</ number > < type >cell</ type > </ phoneNumbers > </ customer > |
Field Access
For this example we will configure our XML binding tools to interact directly with the fields (instance variables).
XStream
XStream uses field access by default.
JAXB
By default JAXB will access public fields and properties. We can configure JAXB to use field access with the following package level annotation:
1 2 3 4 5 | @XmlAccessorType (XmlAccessType.FIELD) package comparison; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; |
Renaming Elements
Next we will look at how to tweak the XML output using the appropriate mapping metadata. First we will rename some elements. As you will see the amount of configuration required is almost identical.
XStream
For XStream we will use @XStreamAlias to configure the root element, and @XStreamImplicit to configure the phoneNumbers property.
For XStream we will use @XStreamAlias to configure the root element, and @XStreamImplicit to configure the phoneNumbers property.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import java.util.ArrayList; import java.util.List; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamImplicit; @XStreamAlias ( "customer" ) public class Customer { private long id; private String name; private Address address; @XStreamImplicit (itemFieldName= "phone-number" ) private List<PHONENUMBER> phoneNumbers; public Customer() { phoneNumbers = new ArrayList<PHONENUMBER>(); } } </PHONENUMBER></PHONENUMBER> |
JAXB
For JAXB we will use @XmlRootElement to configure the root element, and @XmlElement to configure the phoneNumbers property.
For JAXB we will use @XmlRootElement to configure the root element, and @XmlElement to configure the phoneNumbers property.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Customer { private long id; private String name; private Address address; @XmlElement (name= "phone-number" ) private List<PHONENUMBER> phoneNumbers; public Customer() { phoneNumbers = new ArrayList<PHONENUMBER>(); } } </PHONENUMBER></PHONENUMBER> |
Note: The JAXB Marshal code can now be simplified since we no longer need to supply the root element information:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package comparison.jaxb; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import comparison.Customer; import static comparison.Data.CUSTOMER; public class JAXBDemo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Customer. class ); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true ); marshaller.marshal(CUSTOMER, System.out); } } |
XML Output
At this point the same XML is being produced by XStream and JAXB.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | < customer > < id >123</ id > < name >Jane Doe</ name > < address > < city >Any Town</ city > < street >1 A Street</ street > </ address > < phone-number > < type >work</ type > < number >555-WORK</ number > </ phone-number > < phone-number > < type >cell</ type > < number >555-CELL</ number > </ phone-number > </ customer > |
Change the Order of Elements
We will tweak the document again to make sure that when marshalling an Address object the "street" element will always appear before the "city" element.
XStream
For XStream we will need to change our marshal code. The following is based on instructions given in the XStream FAQ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package comparison.xstream; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.reflection.FieldDictionary; import com.thoughtworks.xstream.converters.reflection.SortableFieldKeySorter; import com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider; import comparison.Address; import static comparison.Data.CUSTOMER; public class XStreamDemo { public static void main(String[] args) { SortableFieldKeySorter sorter = new SortableFieldKeySorter(); sorter.registerFieldOrder(Address. class , new String[] { "street" , "city" }); FieldDictionary fieldDictionary = new FieldDictionary(sorter); Sun14ReflectionProvider reflectionProvider = new Sun14ReflectionProvider(fieldDictionary); XStream xstream = new XStream(reflectionProvider); xstream.autodetectAnnotations( true ); xstream.toXML(CUSTOMER, System.out); } } |
JAXB
For JAXB we can configure the ordering of elements right on the model class. We will use @XmlType to do this.
1 2 3 4 5 6 7 8 9 10 11 | package comparison; import javax.xml.bind.annotation.XmlType; @XmlType (propOrder={ "street" , "city" }) public class Address { private String city; private String street; } |
XML Output
The XML output is the same for both JAXB and XStream.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | < customer > < id >123</ id > < name >Jane Doe</ name > < address > < street >1 A Street</ street > < city >Any Town</ city > </ address > < phone-number > < type >work</ type > < number >555-WORK</ number > </ phone-number > < phone-number > < type >cell</ type > < number >555-CELL</ number > </ phone-number > </ customer > |
Mapping to an Attribute
Now we will look at how to tweak the XML output using the appropriate mapping metadata to produce XML attributes. As you will see the amount of configuration required is almost identical.
XStream
For XStream we will use @XStreamAsAttribute to configure the id property to be represented as an XML attribute.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package comparison; import java.util.ArrayList; import java.util.List; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; import com.thoughtworks.xstream.annotations.XStreamImplicit; @XStreamAlias ( "customer" ) public class Customer { @XStreamAsAttribute private long id; private String name; private Address address; @XStreamImplicit (itemFieldName= "phone-number" ) private List<PHONENUMBER> phoneNumbers; public Customer() { phoneNumbers = new ArrayList<PHONENUMBER>(); } } </PHONENUMBER></PHONENUMBER> |
JAXB
For JAXB we will use @XmlAttribute to configure the id property to be represented as an XML attribute.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package comparison; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Customer { @XmlAttribute private long id; private String name; private Address address; @XmlElement (name= "phone-number" ) private List<PHONENUMBER> phoneNumbers; public Customer() { phoneNumbers = new ArrayList<PHONENUMBER>(); } } </PHONENUMBER></PHONENUMBER> |
XML Output
The XML output is the same for both JAXB and XStream.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | < customer id = "123" > < name >Jane Doe</ name > < address > < city >Any Town</ city > < street >1 A Street</ street > </ address > < phone-number > < type >work</ type > < number >555-WORK</ number > </ phone-number > < phone-number > < type >cell</ type > < number >555-CELL</ number > </ phone-number > </ customer > |
Mapping Objects to Simple Content
To compact our document even further we will map the PhoneNumber class to a complex type with simple content.
XStream
With XStream we can do this using a converter. Examples of creating converters can be found on the XStream website:
We can reference the converter on the phoneNumbers property using @XStreamConverter.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package comparison; import java.util.ArrayList; import java.util.List; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; import com.thoughtworks.xstream.annotations.XStreamConverter; import com.thoughtworks.xstream.annotations.XStreamImplicit; @XStreamAlias ( "customer" ) public class Customer { @XmlAttribute private long id; private String name; private Address address; @XStreamImplicit (itemFieldName= "phone-number" ) @XStreamConverter (PhoneNumberConverter. class ) private List<PHONENUMBER> phoneNumbers; public Customer() { phoneNumbers = new ArrayList<PHONENUMBER>(); } } </PHONENUMBER></PHONENUMBER> |
The converter can be implemented as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package comparison; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; public class PhoneNumberConverter implements Converter { public boolean canConvert(Class clazz) { return PhoneNumber. class == clazz; } public void marshal(Object object, HierarchicalStreamWriter hsw, MarshallingContext mc) { PhoneNumber phoneNumber = (PhoneNumber) object; hsw.addAttribute( "type" , phoneNumber.getType()); hsw.setValue(phoneNumber.getNumber()); } public Object unmarshal(HierarchicalStreamReader hsr, UnmarshallingContext uc) { PhoneNumber phoneNumber = new PhoneNumber(); phoneNumber.setType(hsr.getAttribute( "type" )); phoneNumber.setNumber(hsr.getValue()); return phoneNumber; } } |
JAXB
For JAXB we will use the @XmlAttribute and @XmlValue annotations on the PhoneNumber class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package comparison; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlValue; public class PhoneNumber { @XmlAttribute private String type; @XmlValue private String number; } |
XML Output:
The XML output is the same for both JAXB and XStream.
1 2 3 4 5 6 7 8 9 | < customer id = "123" > < name >Jane Doe</ name > < address > < street >1 A Street</ street > < city >Any Town</ city > </ address > < phone-number type = "work" >555-WORK</ phone-number > < phone-number type = "cell" >555-CELL</ phone-number > </ customer > |
Applying Namespaces
We will now namespace qualify the XML document.
XStream
Namespace support in XStream appears to be limited to the StaxDriver. For more information see:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package comparison.xstream; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.reflection.FieldDictionary; import com.thoughtworks.xstream.converters.reflection.SortableFieldKeySorter; import com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider; import com.thoughtworks.xstream.io.xml.QNameMap; import com.thoughtworks.xstream.io.xml.StaxDriver; import comparison.Address; import static comparison.Data.CUSTOMER; public class XStreamDemo { public static void main(String[] args) { QNameMap nsm = new QNameMap(); StaxDriver staxDriver = new StaxDriver(nsm); SortableFieldKeySorter sorter = new SortableFieldKeySorter(); sorter.registerFieldOrder(Address. class , new String[] { "street" , "city" }); FieldDictionary fieldDictionary = new FieldDictionary(sorter); Sun14ReflectionProvider reflectionProvider = new Sun14ReflectionProvider(fieldDictionary); XStream xstream = new XStream(reflectionProvider, staxDriver); xstream.autodetectAnnotations( true ); xstream.toXML(CUSTOMER, System.out); } } |
Note: With this change I lost XML formatting, the following was produced.
1 2 | < customer xmlns = "http://www.example.com" id = "123" >< name >Jane Doe</ name >< address >< street >1 A Street</ street >< city >Any Town</ city ></ address >< phone-number type = "work" >555-WORK</ phone-number >< phone-number type = "cell" >555-CELL</ phone-number ></ customer > |
JAXB
We can configure the namespace information using the @XmlSchema package level annotation:
We can configure the namespace information using the @XmlSchema package level annotation:
1 2 3 4 5 6 7 8 9 | @XmlAccessorType (XmlAccessType.FIELD) elementFormDefault=XmlNsForm.QUALIFIED) package comparison; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlNsForm; import javax.xml.bind.annotation.XmlSchema; |
The following XML was produced
1 2 3 4 5 6 7 8 9 | < name >Jane Doe</ name > < address > < street >1 A Street</ street > < city >Any Town</ city > </ address > < phone-number type = "work" >555-WORK</ phone-number > < phone-number type = "cell" >555-CELL</ phone-number > </ customer > |
Subscribe to:
Posts (Atom)
Blog Archive
-
▼
2012
(113)
-
▼
February
(16)
- SQL server - export xml to file
- xml file from SQL
- SQL server - generate sitemap table
- java - noclassdeffounderror
- com.sun.org.apache.xerces.internal.dom.ElementNSIm...
- Java - Pass by value/Pass by reference
- @XmlTransient for handling Interfaces
- JAXB - Mapping the unmappable
- JAX vs Extreme
- I.E. Object doesn’t support this property or metho...
- window task manager - create dump file
- JAXB : @XmlSeeAlso, @XmlAnyElement
- Jaxb for interfaces
- Workstation components installed but only the Conf...
- Completely remove an existing SQL Server 2005 inst...
- Remove a component from an existing SQL Server 200...
-
▼
February
(16)