It is vital to continuously analyze your business, consider what kind of data to manage, and update the data accordingly. XML is useful since it is flexible, but it is also important to define the structure and process the XML data based on the structure to make the data reliable. An XML schema is used to define the structure.
An XML schema is updated (evolved) as a result of business analysis. As for evolving the XML schema, these are the typical scenarios.
-
Evolve the XML schema (upward compatibility).
The XML schema is evolved, which is upward compatible with the existing XML schema. By doing so, the existing XML data conforms to the new XML schema without modifying the XML data. -
Evolve the XML schema (no compatibility) and transform the XML data.
The XML schema is evolved but it is not compatible with the existing XML schema. The existing XML data is transformed to fit to the new XML schema. -
Evolve the XML schema (no compatibility) and manage the XML data without transformation.
The XML schema is evolved but it is not compatible with the existing XML schema. The existing XML data is not transformed, and you manage it with the existing XML schema.
This article explains these scenarios.
Evolve the XML schema (upward compatibility)
This scenario evolves the XML schema that is upward compatible with the existing XML schema. By doing so, the existing XML data conforms to the new XML schema without modifying the XML data.
For example, this article uses the following simple customer information. The existing XML schema is in Listing 1. XML data that conforms to the XML schema is in Listing 2.
Listing 1. cust1.xsd (XML schema)
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="phone" type="xs:string"/>
<xs:element name="email" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
|
Listing 2. cust1.xml
<?xml version="1.0"?>
<customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="cust1.xsd">
<name>cust1</name>
<address>address1</address>
<phone>11-2222-3333</phone>
<email>cust1@sample.com</email>
</customer>
|
The XML schema in Listing 1 is registered with the following commands. (For registering XML schema and importing XML data, refer to the first article in this series "Manage XML Schemas in DB2, Part 1: Manage XML schemas and validate XML data" (see Resources for a link).
Note: The DB2 command is not case sensitive. XML data and schema locations are case sensitive. Whether the physical location like '/work/customer1.xsd' is case sensitive depends on the operating system. (Windows® is not case sensitive. Linux® and UNIX® are case sensitive.)
REGISTER XMLSCHEMA 'cust1.xsd' FROM '/work/cust1.xsd' AS SAMPLE2.CUST1; COMPLETE XMLSCHEMA SAMPLE2.CUST1; |
The following commands create the T1 table and import the XML data in Listing 2 into the T1 table.
CREATE TABLE T1 (ID INT NOT NULL PRIMARY KEY, XMLDATA XML NOT NULL); IMPORT FROM /work/cust1.del of del XML FROM /work XMLVALIDATE USING SCHEMA SAMPLE2.CUST1 INSERT INTO T1; |
The cust1.del file used in the above IMPORT command contains the following information. The value 1 is set in the ID column.
1, "<XDS FIL='cust1.xml'/>" |
The following SQL statement is issued to get the XML schema object ID, relational ID, and schema location used for validating each record in the T1 table. The following SQL statement uses an outer join so the result contains records that are not validated and records that are validated with XML schemas that are already dropped.
db2 => SELECT T1.ID,
XMLXSROBJECTID(T1.XMLDATA) OBJECTID,
substr(XSR.OBJECTSCHEMA,1,12) OBJECTSCHEMA,
substr(XSR.OBJECTNAME,1,12) OBJECTNAME,
substr(XSR.SCHEMALOCATION,1,16) SCHEMALOCATION
FROM T1 LEFT OUTER JOIN SYSCAT.XSROBJECTS XSR
ON XMLXSROBJECTID(T1.XMLDATA)=XSR.OBJECTID;
ID OBJECTID OBJECTSCHEMA OBJECTNAME SCHEMALOCATION
----------- -------------------- ------------ ------------ ----------------
1 65020719620281344 SAMPLE2 CUST1 cust2.xsd
1 record(s) selected.
|
The phone element in the sample XML is assumed to have the
home telephone number of the customer. Now you add a cellular phone number to the XML.
You can define a new XML schema that is upward compatible with the existing XML schema. To do so, the existing elements are not changed, but you add a new element for the cellular phone number (cell-phone element), and configure the added element as optional (minOccurs="0"). See Listing 3.
Listing 3. cust2.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="phone" type="xs:string"/>
<xs:element name="cell-phone" minOccurs="0" type="xs:string"/>
<xs:element name="email" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
|
Register the XML schema in Listing 3 with the following commands.
REGISTER XMLSCHEMA 'cust2.xsd' FROM '/work/cust2.xsd' AS SAMPLE2.CUST2; COMPLETE XMLSCHEMA SAMPLE2.CUST2; |
The XML schema cust2.xsd is upward compatible with the XML schema cust1.xsd so that cust1.xsd can be replaced with cust2.xsd.
To do so, issue the following UPDATE XMLSCHEMA command.
UPDATE XMLSCHEMA SAMPLE2.CUST1 WITH SAMPLE2.CUST2; |
This command replaces cust1.xsd registered using relational ID SAMPLE2.CUST1 with cust2.xsd.
Listing 4 is the XML data that conforms to the new XML schema.
Listing 4. cust2.xml
<?xml version="1.0"?>
<customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="cust1.xsd">
<name>cust2</name>
<address>address2</address>
<phone>22-3333-4444</phone>
<cell-phone>090-4444-5555</cell-phone>
<email>cust2@sample.com</email>
</customer>
|
Issue the following command to insert the XML data into the T1 table after validating it with the XML schema with relational ID SAMPLE2.CUST1. It will be successful.
IMPORT FROM /work/cust2.del of del XML FROM /work XMLVALIDATE USING SCHEMA SAMPLE2.CUST1 INSERT INTO T1; |
The cust2.del file used in the above IMPORT command contains the following information. The value 2 is set in the ID column.
2, "<XDS FIL='cust2.xml'/>" |
Issue the following SQL statement again to see which XML schema each XML data set is validated with.
db2 => SELECT T1.ID,
XMLXSROBJECTID(T1.XMLDATA) OBJECTID,
substr(XSR.OBJECTSCHEMA,1,12) OBJECTSCHEMA,
substr(XSR.OBJECTNAME,1,12) OBJECTNAME,
substr(XSR.SCHEMALOCATION,1,16) SCHEMALOCATION
FROM T1 LEFT OUTER JOIN SYSCAT.XSROBJECTS XSR
ON XMLXSROBJECTID(T1.XMLDATA)=XSR.OBJECTID;
ID OBJECTID OBJECTSCHEMA OBJECTNAME SCHEMALOCATION
----------- -------------------- ------------ ------------ ----------------
1 65020719620281344 SAMPLE2 CUST1 cust2.xsd
2 65020719620281344 SAMPLE2 CUST1 cust2.xsd
2 record(s) selected.
|
The XML data whose ID is 2 is validated with the new XML schema. As the above result shows, the object ID is not changed even after updating the XML schema. The previously validated XML data (XML data whose ID is 1 in this example) also conforms to new XML schema.
The relational ID is also unchanged, but the schema location is changed to that of new XML schema. Issue the following SQL statement to get the relational ID and the schema location of each registered XML schema.
db2 => SELECT OBJECTID,
substr(OBJECTSCHEMA,1,12) OBJECTSCHEMA,
substr(OBJECTNAME,1,12) OBJECTNAME,
substr(SCHEMALOCATION,1,16) SCHEMALOCATION
FROM SYSCAT.XSROBJECTS;
OBJECTID OBJECTSCHEMA OBJECTNAME SCHEMALOCATION
-------------------- ------------ ------------ ----------------
65020719620281344 SAMPLE2 CUST1 cust2.xsd
66857945295662336 SAMPLE2 CUST2 cust2.xsd
2 record(s) selected.
|
As the above result shows, the two records point to the same schema location. In this situation, XML data is not validated using the schema location. Validating XML data using the schema location cust2.xsd fails as shown below because it is impossible to tell which of the XML schemas with the cust2.xsd schema location is used.
db2 => INSERT INTO T1(ID, XMLDATA) VALUES (22,
XMLVALIDATE(XMLPARSE(DOCUMENT
'<?xml version="1.0"?>
<customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="cust2.xsd">
<name>cust2-2</name>
<address>address2-2</address>
<phone>33-4444-5555</phone>
<cell-phone>090-5555-6666</cell-phone>
<email>cust2-2@sample.com</email>
</customer>'))
);
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL16196N XML document contains an element "customer" that is not correctly
specified. Reason code = "37" SQLSTATE=2200M
|
If you drop one of the XML schemas as shown below, issuing the above INSERT statement is successful.
DROP XSROBJECT SAMPLE2.CUST2; |
Therefore, the new XML schema needs to be dropped after replacing the existing XML schema with the new XML schema. For this purpose, the DROP NEW SCHEMA option can be used with the UPDATE XMLSCHEMA command.
UPDATE XMLSCHEMA SAMPLE2.CUST1 WITH SAMPLE2.CUST2 DROP NEW SCHEMA; |
Another consideration is that the schema location is also replaced with the new one. As a result, the schema location contained in the existing XML data doesn't match. This can be solved by registering the new XML schema with the existing schema location as shown below.
REGISTER XMLSCHEMA 'cust1.xsd' FROM '/work/cust2.xsd' AS SAMPLE2.CUST2; COMPLETE XMLSCHEMA SAMPLE2.CUST2; |
Then update the XML schema again with the DROP NEW SCHEMA option.
UPDATE XMLSCHEMA SAMPLE2.CUST1 WITH SAMPLE2.CUST2 DROP NEW SCHEMA; |
By doing so, even after replacing the XML schema, the schema location can be used when validating XML data.
If the XML schema is evolved as upward compatible with the existing XML schema, the
existing XML data can be managed with the new XML schema without any modifications. On
the other hand, newly added elements and attributes must be optional to keep upward compatibility so that you cannot
validate their existence even if you want newly added information to be required. (In
the above example, the cell-phone element is added. But it
is added as optional so XML data without the cell-phone element is also validated successfully.) For other requirements for upward compatibility, refer to the DB2 Information Center and the developerWorks article, "Evolving your XML schemas using DB2 pureXML". See Resources for the links.
Evolve the XML schema (no compatibility) and transform the XML data
This scenario evolves the XML schema that is not compatible with the existing XML schema. The existing XML data is transformed to fit to the new XML schema.
Listing 5 adds home and cell elements under the phone element,
and those elements manage the home telephone and cellular phone numbers of a
customer accordingly. Its XML schema is in Listing 6.
Listing 5. cust3.xml
<?xml version="1.0"?>
<customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="cust3.xsd">
<name>cust3</name>
<address>address3</address>
<phone>
<home>44-5555-6666</home>
<cell>090-6666-7777</cell>
</phone>
<email>cust3@sample.com</email>
</customer>
|
Listing 6. cust3.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="phone" type="phoneType"/>
<xs:element name="email" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="phoneType">
<xs:sequence>
<xs:element name="home" type="xs:string"/>
<xs:element name="cell" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
|
The XML schema and XML data (in Listings 5 and 6) are registered and imported as shown below.
REGISTER XMLSCHEMA 'cust3.xsd' FROM '/work/cust3.xsd' AS SAMPLE2.CUST3; COMPLETE XMLSCHEMA SAMPLE2.CUST3; IMPORT FROM /work/cust3.del of del XML FROM /work XMLVALIDATE USING SCHEMA SAMPLE2.CUST3 INSERT INTO T1; |
The cust3.del file used in the above IMPORT command contains the following information. The value 3 is set in the ID column.
3, "<XDS FIL='cust3.xml'/>" |
Issue the following SQL statement again to get which XML schema each XML data is validated with.
db2 => SELECT T1.ID,
XMLXSROBJECTID(T1.XMLDATA) OBJECTID,
substr(XSR.OBJECTSCHEMA,1,12) OBJECTSCHEMA,
substr(XSR.OBJECTNAME,1,12) OBJECTNAME,
substr(XSR.SCHEMALOCATION,1,16) SCHEMALOCATION
FROM T1 LEFT OUTER JOIN SYSCAT.XSROBJECTS XSR
ON XMLXSROBJECTID(T1.XMLDATA)=XSR.OBJECTID;
ID OBJECTID OBJECTSCHEMA OBJECTNAME SCHEMALOCATION
----------- -------------------- ------------ ------------ ----------------
1 65020719620281344 SAMPLE2 CUST1 cust1.xsd
2 65020719620281344 SAMPLE2 CUST1 cust1.xsd
22 65020719620281344 SAMPLE2 CUST1 cust1.xsd
3 68398419340809216 SAMPLE2 CUST3 cust3.xsd
4 record(s) selected.
|
XML data with the IDs of 1, 2, and 22 conform to XML schema cust2.xsd in Listing 3. (The XML schema using the relational ID SAMPLE2.CUST1 is replaced with cust2.xsd in Listing 3 which is registered as the schema location cust1.xsd) Those XML data sets need to be changed as follows to fit to cust3.xsd.
-
The
homeandcellelements need to be added under the/customer/phone. -
The value of
/customer/phoneis moved to/customer/phone/home. -
If
/customer/cell-phoneis defined, the value is moved to/customer/phone/cell, and/customer/cell-phoneis deleted. -
The value of the
xsi:noNamespaceSchemaLocationattribute is changed to cust3.xsd. (This is not required if the relational ID is used when validating XML data.)
Issue the following SQL statement to apply the above changes against XML data that have been validated with XML schema using the relational ID SAMPLE2.CUST1, and validate the changed XML data with the XML schema using the schema location cust3.xsd.
UPDATE T1
SET XMLDATA=XMLVALIDATE(XMLQUERY(
'declare namespace xsi="http://www.w3.org/2001/XMLSchema-instance";
copy $new := $XMLDATA
modify (
do replace $new/customer/phone with
<phone>
<home>{$new/customer/phone/text()}</home>
<cell>{$new/customer/cell-phone/text()}</cell>
</phone>,
do replace value of $new/customer/@xsi:noNamespaceSchemaLocation with "cust3.xsd",
do delete $new/customer/cell-phone )
return $new'))
WHERE XMLXSROBJECTID(XMLDATA)=(SELECT OBJECTID FROM SYSCAT.XSROBJECTS WHERE
OBJECTSCHEMA='SAMPLE2' AND OBJECTNAME='CUST1')
|
Issue the following SQL statement again to see which XML schema each XML data is validated with. The result shows all the records are validated with XML schema using the schema location cust3.xsd.
db2 => SELECT T1.ID,
XMLXSROBJECTID(T1.XMLDATA) OBJECTID,
substr(XSR.OBJECTSCHEMA,1,12) OBJECTSCHEMA,
substr(XSR.OBJECTNAME,1,12) OBJECTNAME,
substr(XSR.SCHEMALOCATION,1,16) SCHEMALOCATION
FROM T1 LEFT OUTER JOIN SYSCAT.XSROBJECTS XSR
ON XMLXSROBJECTID(T1.XMLDATA)=XSR.OBJECTID;
ID OBJECTID OBJECTSCHEMA OBJECTNAME SCHEMALOCATION
----------- -------------------- ------------ ------------ ----------------
1 68398419340809216 SAMPLE2 CUST3 cust3.xsd
2 68398419340809216 SAMPLE2 CUST3 cust3.xsd
22 68398419340809216 SAMPLE2 CUST3 cust3.xsd
3 68398419340809216 SAMPLE2 CUST3 cust3.xsd
4 record(s) selected.
|
Issue the following SQL statement to see the ID and XML data in the T1 table.
SELECT ID, XMLSERIALIZE(XMLDATA AS VARCHAR(500)) FROM T1; |
You can add or change a namespace by using UPDATE statement, but you need to map all elements. If cust3.xsd in Listing 6 has the namespace "http://www.sample.com/customer3", the following UPDATE statement works.
UPDATE T1
SET XMLDATA=XMLVALIDATE(XMLQUERY(
'declare namespace xsi="http://www.w3.org/2001/XMLSchema-instance";
declare namespace cust="http://www.sample.com/customer3";
copy $new := $XMLDATA
modify (
do replace $new/customer with
<cust:customer xsi:schemaLocation="http://www.sample.com/customer3 cust3.xsd">
<cust:name>{$new/customer/name/text()}</cust:name>
<cust:address>{$new/customer/address/text()}</cust:address>
<cust:phone>
<cust:home>{$new/customer/phone/text()}</cust:home>
<cust:cell>{$new/customer/cell-phone/text()}</cust:cell>
</cust:phone>
<cust:email>{$new/customer/email/text()}</cust:email>
</cust:customer> )
return $new'))
WHERE XMLXSROBJECTID(XMLDATA)=(SELECT OBJECTID FROM SYSCAT.XSROBJECTS WHERE
OBJECTSCHEMA='SAMPLE2' AND OBJECTNAME='CUST1')
|
Evolve the XML schema (no compatibility) and manage the XML data without transformation
This scenario evolves the XML schema that is not compatible with the existing XML schema. The existing XML data is not transformed, and you manage it with the existing XML schema. DB2 can contain different types of XML data in the same column.
This scenario requires an application to process each XML data set with its XML schema.
I've already mentioned the problem about evolving an XML schema with upward compatibility, where the existence of newly added elements and attributes cannot be checked. In this scenario, it is possible to check them. And, if existing elements and attributes are not changed, the same program can be used with different XML schemas. (But you need to handle the case that the values of newly added elements and attributes cannot be obtained.)
In the example in Figure 1, the application keeps pairs of XML schema object IDs and their versions. The versions are what you assign, and you know the XML structure (that is, XML schema) from the version. You can use relational ID or schema location as version. When getting XML data, the application also gets the XML schema object ID. Then the application identifies the XML schema from the version associated with the schema object ID, and processes the XML data based on its version.
Figure 1. Process XML data, where each XML data is validated with one of different XML schemas
In the example in Figure 2, the application identifies the XML schema used for XML data from another column value (creation date in this example). When getting XML data, the application also gets the column data for identifying the XML schema, and processes the XML data based on it. In Figure 2, the application holds a table where relational ID is associated with creation date range. Instead of relational ID, you can use schema location or something like version number to identify the XML schema.
Figure 2. Process XML data, where each XML data is validated with one of different XML schemas
Instead of validating XML data by using XMLVALIDATE function/option with the INSERT/UPDATE statements or IMPORT command, you can use triggers. The following "CREATE TRIGGER" statements are for the UPDATE statement to validate XML data with the XML schema of the relational ID SAMPLE2.ORDER2008 if the CREATION_DATE column value is equal to or greater than 2008-01-01 (Listing 7), to validate XML data with the XML schema using the relational ID SAMPLE2.ORDER2002 if the CREATION_DATE column value is between 2002-01-01 and 2007-12-31 (Listing 8). You can do the same thing for the INSERT statement, which is also affected to the IMPORT command. There is LOAD command that is similar to IMPORT command. Though LOAD command doesn't invoke trigger, it has XMLVALIDATE option whose syntax is the same as that of IMPORT command.
Listing 7. Trigger for validating XML data whose CREATION_DATE column value is equal or more than "2008-01-01"
CREATE TRIGGER UPDATE_ORDER2008 NO CASCADE BEFORE UPDATE ON SAMPLE2.ORDER REFERENCING NEW AS N FOR EACH ROW WHEN (N.CREATION_DATE >= '2008-01-01') BEGIN ATOMIC SET (N.XMLDATA) = XMLVALIDATE(N.XMLDATA ACCORDING TO XMLSCHEMA ID SAMPLE2.ORDER2008); END |
Listing 8. Trigger for validating XML data whose CREATION_DATE column value is between 2002-01-01 and 2007-12-31
CREATE TRIGGER UPDATE_ORDER2002 NO CASCADE BEFORE UPDATE ON SAMPLE2.ORDER REFERENCING NEW AS N FOR EACH ROW WHEN (N.CREATION_DATE < '2008-01-01' AND N.CREATION_DATE >= '2002-01-01') BEGIN ATOMIC SET (N.XMLDATA) = XMLVALIDATE(N.XMLDATA ACCORDING TO XMLSCHEMA ID SAMPLE2.ORDER2002); END |
When XML data is evolved which is upward compatible with the existing XML schema, you can manage the existing XML data with the new XML schema without any modification. Even after evolving the XML schema, you can use either the relational IDs or schema locations to identify the XML schema used for validating XML data. But when using the schema location, new XML schema must be dropped after replacing the existing XML schema with new one. Also, when registering new XML schema before replacing the existing XML schema, you need to register it with the same schema location as the existing XML schema.
A concern with evolving XML schema with upward compatibility is that XML data cannot be validated with the existence of newly added elements and attributes. Another concern is that XML data is likely to look bad by reflecting new requirements, which may lead error-prone. To solve those concerns, you need to evolve an XML schema that is not compatible with the existing XML schema. There are two scenarios for that: Transform existing XML data to be compatible with new XML schema or manage XML data as it is with its XML schema.
Learn
- Manage XML Schemas in DB2, Part 1: Manage XML schemas and validate XML data (Masahiro Ohkawa, developerWorks, February 2010): Read the first article in this series as you explore both schema location and a relational ID to manage XML schemas and validate XML data.
- IBM DB2 9.7 for Linux, UNIX and Windows Information Center: Find more information about evolving schemas and using the DB2 commands.
- Altering registered XSR objects: Get more information in the DB2 Information Center for registering XSR objects.
- Evolving an XML schema: Read this section in the DB2 Information center to learn more.
- REGISTER XMLSCHEMA command: See the DB2 documentation for more information about this command.
- UPDATE XMLSCHEMA command: Find the command syntax for this command in the DB2 Information Center.
- SYSCAT.XSROBJECTS catalog view: Learn more in the DB2 Information Center.
- XMLXSROBJECTID scalar function:Read more about this function in the DB2 Information Center.
- XMLVALIDATE function: See the DB2 documentation for more information about this function.
- IMPORT command: See the DB2 documentation for more information about the IMPORT command.
- Trigger processing of XML data: See this section in the DB2 Information Center for more information about using triggers to process XML data.
- DB2 9 pureXML Guide: : Find information about the pureXML data store, hybrid database design, and administration in this IBM Redbook.
- Evolving your XML schemas using DB2 pureXML (Khurram Faraaz, Ronny Bartsch, Susan Malaika, developerWorks, March 2008): Learn how to handle changes to evolving XML schemas using the DB2 pureXML Schema Registry (XSR) features.
- "Preserving XML queries during schema evolution" (Mirella Moura Moro, Susan Malaika, Lifyeow Lim, developerWorks, June 2007): Explore a guide to writing queries that behave well across XML schema changes. This article extends a taxonomy of changes that might apply to an XML schema during its evolution. It then examines the impact of those changes on the schema validation process (both forward and backward validations) and query evaluation.
- Update XML in DB2 9.5, (Matthias Nicola, Uttam Jain, developerWorks, October 2007): The XQuery Update Facility allows you to modify, insert, or delete individual elements and attributes within an XML document. In this article, find more about the new XML XQuery Update Facility functionality, examples of typical XML update operations, and how to avoid common pitfalls.
- Getting Started with IBM DB2 Express-C: Visit the home page for DB2 Express-C.
- XML area on developerWorks: Get the resources you need to advance your skills in the XML arena.
- IBM XML certification: Find out how you can become an IBM-Certified Developer in XML and related technologies.
- XML technical library: See the developerWorks XML Zone for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks.
- developerWorks technical events and webcasts: Stay current with technology in these sessions.
- developerWorks
podcasts: Listen to interesting interviews and discussions for software developers.
Get products and technologies
- IBM product evaluation versions: Download or explore the online trials in the IBM SOA Sandbox and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
Discuss
- Participate in the discussion forum.
- XML zone discussion forums: Participate in any of several XML-related discussions.
- developerWorks blogs: Check out these blogs and get involved.





