Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Xml Java

2,848 views

Published on

Published in: Technology, Education
  • Be the first to comment

  • Be the first to like this

Xml Java

  1. 1. XML and Java Alex Chaffee, alex@jguru.com http://www.purpletech.com
  2. 2. Overview <ul><li>Why Java and XML? </li></ul><ul><li>Parsers: DOM, JDOM, SAX </li></ul><ul><li>Using XML from JSP </li></ul><ul><li>Java/XML Object Mapping </li></ul><ul><li>Resources </li></ul>
  3. 3. Why Java/XML? <ul><li>XML maps well to Java </li></ul><ul><ul><li>late binding </li></ul></ul><ul><ul><li>hierarchical (OO) data model </li></ul></ul><ul><li>Unicode support in Java </li></ul><ul><li>XML Structures map well to Java Objects </li></ul><ul><li>Portability </li></ul><ul><li>Network friendly </li></ul>
  4. 4. XML Parsers <ul><li>Validating/Non-Validating </li></ul><ul><li>Tree-based </li></ul><ul><li>Event-based </li></ul><ul><li>SAX-compliance </li></ul><ul><li>Not technically parsers </li></ul><ul><ul><li>XSL </li></ul></ul><ul><ul><li>XPath </li></ul></ul>
  5. 5. Some Java XML Parsers <ul><li>DOM </li></ul><ul><ul><li>Sun JAXP </li></ul></ul><ul><ul><li>IBM XML4J </li></ul></ul><ul><ul><li>Apache Xerces </li></ul></ul><ul><ul><li>Resin (Caucho) </li></ul></ul><ul><ul><li>DXP (DataChannel) </li></ul></ul><ul><li>SAX </li></ul><ul><ul><li>Sun JAXP </li></ul></ul><ul><ul><li>SAXON </li></ul></ul><ul><li>JDOM </li></ul>
  6. 6. Dom API <ul><li>Tree-based </li></ul><ul><li>Node classes </li></ul><ul><li>Part of W3C spec </li></ul><ul><li>Sorting/Modifying of Elements </li></ul><ul><li>Sharing document with other applications </li></ul>
  7. 7. XML is a Tree <ul><li><?xml version=&quot;1.0&quot;?> </li></ul><ul><li><!DOCTYPE menu SYSTEM &quot;menu.dtd&quot;> </li></ul><ul><li><menu> </li></ul><ul><li><meal name=&quot;breakfast&quot;> </li></ul><ul><li><food>Scrambled Eggs</food> </li></ul><ul><li><food>Hash Browns</food> </li></ul><ul><li><drink>Orange Juice</drink> </li></ul><ul><li></meal> </li></ul><ul><li><meal name=&quot;snack&quot;> </li></ul><ul><li><food>Chips</food> </li></ul><ul><li></meal> </li></ul><ul><li></menu> </li></ul>menu meal name &quot;breakfast&quot; food &quot;Scrambled Eggs&quot; food &quot;Hash Browns&quot; drink &quot;Orange Juice&quot; meal
  8. 8. DOM API (cont’d) <ul><li>Based on Interfaces </li></ul><ul><ul><li>Good design style - separate interface from implementation </li></ul></ul><ul><ul><li>Document, Text, Processing Instruction, Element - ALL are interfaces </li></ul></ul><ul><ul><li>All extend interface Node </li></ul></ul><ul><ul><li>Including interface Attr (parentNode is null, etc) </li></ul></ul>
  9. 9. DOM Example public void print(Node node) { //recursive method call using DOM API... int type = node.getNodeType(); case Node.ELEMENT_NODE: // print element with attributes out.print('<'); out.print(node.getNodeName()); Attr attrs[] = node.getAttributes(); for (int i = 0; i < attrs.length; i++) { Attr attr = attrs[i]; out.print(' '); out.print(attr.getNodeName());out.print(&quot;=&quot;&quot;); out.print(normalize(attr.getNodeValue())); out.print('&quot;'); } out.print('>'); NodeList children = node.getChildNodes(); if (children != null) { int len = children.getLength(); for (int i = 0; i < len; i++) { print(children.item(i)); } } break; case Node.ENTITY_REFERENCE_NODE: // handle entity reference nodes // ...
  10. 10. DOM API Highlights <ul><li>Node </li></ul><ul><ul><li>getNodeType() </li></ul></ul><ul><ul><li>getNodeName() </li></ul></ul><ul><ul><li>getNodeValue() </li></ul></ul><ul><ul><ul><li>returns null for Elements </li></ul></ul></ul><ul><ul><li>getAttributes() </li></ul></ul><ul><ul><ul><li>returns null for non-Elements </li></ul></ul></ul><ul><ul><li>getChildNodes() </li></ul></ul><ul><ul><li>getParentNode() </li></ul></ul><ul><li>Element </li></ul><ul><ul><li>getTagName() </li></ul></ul><ul><ul><ul><li>same as getNodeName() </li></ul></ul></ul><ul><ul><li>getElementsByTagName(String tag) </li></ul></ul><ul><ul><ul><li>get all children of this name, recursively </li></ul></ul></ul><ul><ul><li>normalize() </li></ul></ul><ul><ul><ul><li>smooshes text nodes together </li></ul></ul></ul><ul><li>Attr </li></ul><ul><ul><li>attributes are not technically child nodes </li></ul></ul><ul><ul><li>getParent() et al. return null </li></ul></ul><ul><ul><li>getName(), getValue() </li></ul></ul><ul><li>Document </li></ul><ul><ul><li>has one child node - the root element </li></ul></ul><ul><ul><ul><li>call getDocumentElement() </li></ul></ul></ul><ul><ul><li>contains factory methods for creating attributes, comments, etc. </li></ul></ul>
  11. 11. DOM Level 2 <ul><li>Adds namespace support, extra methods </li></ul><ul><li>Not supported by Java XML processors yet </li></ul>
  12. 12. The Trouble With DOM <ul><li>Written by C programmers </li></ul><ul><li>Cumbersome API </li></ul><ul><ul><li>Node does double-duty as collection </li></ul></ul><ul><ul><li>Multiple ways to traverse, with different interfaces </li></ul></ul><ul><li>Tedious to walk around tree to do simple tasks </li></ul><ul><li>Doesn't support Java standards (java.util collections) </li></ul>
  13. 13. JDOM: Better than DOM <ul><li>Java from the ground up </li></ul><ul><li>Open source </li></ul><ul><li>Clean, simple API </li></ul><ul><li>Uses Java Collections </li></ul>
  14. 14. JDOM vs. DOM <ul><li>Classes / Interfaces </li></ul><ul><li>Java / Many languages </li></ul><ul><li>Java Collections / Idiosyncratic collections </li></ul><ul><li>getChildText() and other useful methods / getNextSibling() and other useless methods </li></ul>
  15. 15. JDOM: The Best of Both Worlds <ul><li>Clean, easy to use API </li></ul><ul><ul><li>document.getRootElement().getChild(&quot;book&quot;). getChildText(&quot;title&quot;) </li></ul></ul><ul><li>Random-access tree model (like DOM) </li></ul><ul><li>Can use SAX for backing parser </li></ul><ul><li>Open Source, not Standards Committee </li></ul><ul><ul><li>Allowed benevolent dictatorship -> clean design </li></ul></ul>
  16. 16. JDOM Example XMLOutputter out = new XMLOutputter(); out.output( element, System.out ); Or… public void print(Element node) { //recursive method call using JDOM API... out.print('<'); out.print(node.getName()); List attrs = node.getAttributes(); for (int i = 0; i < attrs.size(); i++) { Attribute attr = (Attribute)attrs.get(i); out.print(' '); out.print(attr.getName());out.print(&quot;=&quot;&quot;); out.print(attr.getValue() ); out.print('&quot;'); } out.print('>'); List children = node.getChildren(); if (children != null) { for (int i = 0; i < children.size(); i++) { print(children.item(i)); } }
  17. 17. JDOM Example <ul><li>public Element toElement(User dobj) throws IOException </li></ul><ul><li>{ </li></ul><ul><li>User obj = (User)dobj; </li></ul><ul><li>Element element = new Element(&quot;user&quot;); </li></ul><ul><li>element.addAttribute(&quot;userid&quot;, &quot;&quot;+user.getUserid()); </li></ul><ul><li>String val; </li></ul><ul><li>val = obj.getUsername(); </li></ul><ul><li>if (val != null) { </li></ul><ul><li> element.addChild(new Element(&quot;username&quot;).setText(val)); </li></ul><ul><li>} </li></ul><ul><li>val = obj.getPasswordEncrypted(); </li></ul><ul><li>if (val != null) { </li></ul><ul><li> element.addChild(new Element(&quot;passwordEncrypted&quot;).setText(val)); </li></ul><ul><li>} </li></ul><ul><li>return element; </li></ul><ul><li>} </li></ul>
  18. 18. JDOM Example <ul><li>public User fromElement(Element element) throws DataObjectException </li></ul><ul><li>{ </li></ul><ul><li>List list; </li></ul><ul><li>User obj = new User(); </li></ul><ul><li>String value = null; </li></ul><ul><li>Attribute userid = element.getAttribute(&quot;userid&quot;); </li></ul><ul><li>if (userid != null) { </li></ul><ul><li> obj.setUserid( userid.getIntValue() ); </li></ul><ul><li>} </li></ul><ul><li>value = element.getChildText(&quot;username&quot;); </li></ul><ul><li>if (value != null) { </li></ul><ul><li> obj.setUsername( value ); </li></ul><ul><li>} </li></ul><ul><li>value = element.getChildText(&quot;passwordEncrypted&quot;); </li></ul><ul><li>if (value != null) { </li></ul><ul><li> obj.setPasswordEncrypted( value ); </li></ul><ul><li>} </li></ul><ul><li>return obj; </li></ul><ul><li>} </li></ul>
  19. 19. DOMUtils <ul><li>DOM is clunky </li></ul><ul><li>DOMUtils.java - set of utilities on top of DOM </li></ul><ul><li>http://www.purpletech.com/code </li></ul><ul><li>Or just use JDOM </li></ul>
  20. 20. Event-Based Parsers <ul><li>Scans document top to bottom </li></ul><ul><li>Invokes callback methods </li></ul><ul><li>Treats XML not like a tree, but like a list (of tags and content) </li></ul><ul><li>Pro: </li></ul><ul><ul><li>Not necessary to cache entire document </li></ul></ul><ul><ul><li>Faster, smaller, simpler </li></ul></ul><ul><li>Con: </li></ul><ul><ul><li>must maintain state on your own </li></ul></ul><ul><ul><li>can't easily backtrack or skip around </li></ul></ul>
  21. 21. SAX API <ul><li>Grew out of xmldev mailing list (grassroots) </li></ul><ul><li>Event-based </li></ul><ul><li>startElement(), endElement() </li></ul><ul><li>Application intercepts events </li></ul><ul><li>Not necessary to cache entire document </li></ul>
  22. 22. Sax API (cont’d) <ul><li>public void startElement(String name, AttributeList atts) { </li></ul><ul><li>// perform implementation </li></ul><ul><li>out.print(“Element name is “ + name); </li></ul><ul><li>out.print(“, first attribute is “ + atts.getName(0) </li></ul><ul><li>+ “, value is “ + atts.getValue(0)); </li></ul><ul><li>} </li></ul>
  23. 23. XPath <ul><li>The stuff inside the quotes in XSL </li></ul><ul><li>Directory-path metaphor for navigating XML document </li></ul><ul><ul><li>&quot;/curriculum/class[4]/student[first()]&quot; </li></ul></ul><ul><li>Implementations </li></ul><ul><ul><li>Resin (Caucho) built on DOM </li></ul></ul><ul><ul><li>JDOM has one in the &quot;contrib&quot; package </li></ul></ul><ul><li>Very efficient API for extracting specific info from an XML tree </li></ul><ul><ul><li>Don't have to walk the DOM or wait for the SAX </li></ul></ul><ul><ul><li>Con: yet another syntax / language, without full access to Java libraries </li></ul></ul>
  24. 24. XSL <ul><li>eXtensible Stylesheet Language </li></ul><ul><li>transforms one XML document into another </li></ul><ul><li>XSL file is a list of rules </li></ul><ul><li>Java XSL processors exist </li></ul><ul><ul><li>Apache Xalan </li></ul></ul><ul><ul><ul><li>(not to be confused with Apache Xerces) </li></ul></ul></ul><ul><ul><li>IBM LotusXSL </li></ul></ul><ul><ul><li>Resin </li></ul></ul><ul><ul><li>SAXON </li></ul></ul><ul><ul><li>XT </li></ul></ul>
  25. 25. Trouble with XSL <ul><li>It's a programming language masquerading as a markup language </li></ul><ul><li>Difficult to debug </li></ul><ul><li>Turns traditional programming mindset on its head </li></ul><ul><ul><li>Declarative vs. procedural </li></ul></ul><ul><ul><li>Recursive, like Prolog </li></ul></ul><ul><li>Doesn't really separate presentation from code </li></ul>
  26. 26. JSP <ul><li>JavaServer Pages </li></ul><ul><li>Outputting XML </li></ul><ul><li><% </li></ul><ul><li>User = loadUser(request.getParameter(&quot;username&quot;)); </li></ul><ul><li>response.setContentType(&quot;text/xml&quot;); </li></ul><ul><li>%> </li></ul><ul><li><user> </li></ul><ul><li><username><%=user.getUsername()%></username> </li></ul><ul><li><realname><%=user.getRealname()%></realname> </li></ul><ul><li></user> </li></ul><ul><li>Can also output HTML based on XML parser, naturally (see my &quot;JSP and XML&quot; talk, or http://www.purpletech.com) </li></ul>
  27. 27. XMLC <ul><li>A radical solution to the problem of how to separate presentation template from logic… </li></ul><ul><li>…to actually separate the presentation template from the logic! </li></ul>
  28. 28. XMLC Architecture HTML (with ID tags) Java Class (e.g. Servlet) HTML Object (automatically generated) XMLC HTML (dynamically-generated) Setting values Data Reading data
  29. 29. XMLC Details <ul><li>Open-source (xmlc.enhydra.org) </li></ul><ul><li>Uses W3C DOM APIs </li></ul><ul><li>Generates &quot;set&quot; methods per tag </li></ul><ul><ul><li>Source: <H1 id=&quot;title&quot;>Hello</H1> </li></ul></ul><ul><ul><li>Code: obj.setElementTitle(&quot;Goodbye&quot;) </li></ul></ul><ul><ul><li>Output: <H1>Goodbye</H1> </li></ul></ul><ul><li>Allows graphic designers and database programmers to develop in parallel </li></ul><ul><li>Works with XML source too </li></ul>
  30. 30. XML and Java in 2001 <ul><li>Many apps' config files are in XML </li></ul><ul><ul><li>Ant </li></ul></ul><ul><ul><li>Tomcat </li></ul></ul><ul><ul><li>Servlets </li></ul></ul><ul><li>Several XML-based Sun APIs </li></ul><ul><ul><li>JAXP </li></ul></ul><ul><ul><li>JAXM </li></ul></ul><ul><ul><li>ebXML </li></ul></ul><ul><ul><li>SOAP (half-heartedly supported  ) </li></ul></ul>
  31. 31. Java XML Documentation <ul><li>Jdox </li></ul><ul><ul><li>Javadoc -> single XML file </li></ul></ul><ul><ul><li>http://www.componentregistry.com/ </li></ul></ul><ul><ul><li>Ready for transformation (e.g. XSL) </li></ul></ul><ul><li>Java Doclet </li></ul><ul><ul><li>http://www.sun.com/xml/developers/doclet </li></ul></ul><ul><ul><li>Javadoc -> multiple XML files (one per class) </li></ul></ul><ul><li>Cocoon </li></ul><ul><ul><li>Has alpha XML doclet </li></ul></ul>
  32. 32. Soapbox: DTDs are irrelevant <ul><li>DTDs describe structure of an unknown document </li></ul><ul><li>But in most applications, you already know the structure – it's implicit in the code </li></ul><ul><li>If the document does not conform, there will be a runtime error, and/or corrupt/null data </li></ul><ul><li>This is as it should be! GIGO. </li></ul><ul><li>You could have a separate &quot;sanity check&quot; phase, but parsing with validation &quot;on&quot; just slows down your app </li></ul><ul><li>Useful for large-scale document-processing applications, but not for custom apps or transformations </li></ul>
  33. 33. XML and Server-Side Java
  34. 34. Server-Side Java-XML Architecture <ul><li>Many possible architectures </li></ul><ul><ul><li>XML Data Source </li></ul></ul><ul><ul><ul><li>disk or database or other data feed </li></ul></ul></ul><ul><ul><li>Java API </li></ul></ul><ul><ul><ul><li>DOM or SAX or XPath or XSL </li></ul></ul></ul><ul><ul><li>XSL </li></ul></ul><ul><ul><ul><li>optional transformation into final HTML, or HTML snippets, or intermediate XML </li></ul></ul></ul><ul><ul><li>Java Business Logic </li></ul></ul><ul><ul><ul><li>JavaBeans and/or EJB </li></ul></ul></ul><ul><ul><li>Java Presentation Code </li></ul></ul><ul><ul><ul><li>Servlets and/or JSP and/or XMLC </li></ul></ul></ul>
  35. 35. Server-Side Java-XML Architecture Java UI Java Business Logic XML Processors XML Data Sources HTML JSP JavaBeans Servlet EJB DOM, SAX XPath XSL Filesystem XML-savvy RDBMS XML Data Feed
  36. 36. Server-Side Architecture Notes <ul><li>Note that you can skip any layer, and/or call within layers </li></ul><ul><ul><li>e.g. XML->XSL->DOM->JSP, or </li></ul></ul><ul><ul><li>JSP->Servlet->DOM->XML </li></ul></ul>
  37. 37. Cache as Cache Can <ul><li>Caching is essential </li></ul><ul><li>Whatever its advantages, XML is slow </li></ul><ul><li>Cache results on disk and/or in memory </li></ul>
  38. 38. XML <-> Java Object Mapping
  39. 39. XML and Object Mapping <ul><li>Java -> XML </li></ul><ul><ul><li>Start with Java class definitions </li></ul></ul><ul><ul><li>Serialize them - write them to an XML stream </li></ul></ul><ul><ul><li>Deserialize them - read values in from previously serialized file </li></ul></ul><ul><li>XML -> Java </li></ul><ul><ul><li>Start with XML document type </li></ul></ul><ul><ul><li>Generate Java classes that correspond to elements </li></ul></ul><ul><ul><li>Classes can read in data, and write in compatible format (shareable) </li></ul></ul>
  40. 40. Java -> XML Implementations <ul><li>Java -> XML </li></ul><ul><ul><li>BeanML </li></ul></ul><ul><ul><li>Coins / BML </li></ul></ul><ul><ul><li>Sun's XMLOutputStream/XMLInputStream </li></ul></ul><ul><ul><li>XwingML (Bluestone) </li></ul></ul><ul><ul><li>JDOM BeanMapper </li></ul></ul><ul><ul><li>Quick? </li></ul></ul><ul><ul><li>JSP (must roll your own) </li></ul></ul>
  41. 41. BeanML Code (Extract) <ul><li><?xml version=&quot;1.0&quot;?> </li></ul><ul><li><bean class=&quot;java.awt.Panel&quot;> </li></ul><ul><li><property name=&quot;background&quot; value=&quot;0xeeeeee&quot;/> </li></ul><ul><li><property name=&quot;layout&quot;> </li></ul><ul><li><bean class=&quot;java.awt.BorderLayout&quot;/> </li></ul><ul><li></property> </li></ul><ul><li><add> </li></ul><ul><li><bean class=&quot;demos.juggler.Juggler&quot; id=&quot;Juggler&quot;> </li></ul><ul><li><property name=&quot;animationRate&quot; value=&quot;50&quot;/> </li></ul><ul><li><call-method name=&quot;start&quot;/> </li></ul><ul><li></bean> </li></ul><ul><li><string>Center</string> </li></ul><ul><li></add> </li></ul><ul><li>… </bean> </li></ul>
  42. 42. Coins <ul><li>Part of MDSAX </li></ul><ul><li>Connect XML Elements and JavaBeans </li></ul><ul><li>Uses Sax Parser, Docuverse DOM to convert XML into JavaBean </li></ul><ul><li>Uses BML - (Bindings Markup Language) to define mapping of XML elements to Java Classes </li></ul>
  43. 43. JDOM BeanMapper <ul><li>Written by Alex Chaffee  </li></ul><ul><li>Default implementation outputs element-only XML, one element per property, named after property </li></ul><ul><li>Also goes other direction (XML->Java) </li></ul><ul><ul><li>Doesn't (yet) automatically build bean classes </li></ul></ul><ul><li>Can set mapping to other custom element names / attributes </li></ul>
  44. 44. XMLOutputStream/XMLInputStream <ul><li>From some Sun engineers </li></ul><ul><ul><li>http://java.sun.com/products/jfc/tsc/articles/persistence/ </li></ul></ul><ul><li>May possibly become core, but unclear </li></ul><ul><li>Serializes Java classes to and from XML </li></ul><ul><li>Works with existing Java Serialization </li></ul><ul><li>Not tied to a specific XML representation </li></ul><ul><ul><li>You can build your own plug-in parser </li></ul></ul><ul><li>Theoretically, can be used for XML->Java as well </li></ul>
  45. 45. XMLOutputStream/XMLInputStream
  46. 47. XML -> Java Implementations <ul><li>XML -> Java </li></ul><ul><ul><li>Java-XML Data Binding (JSR 31 / Adelard) </li></ul></ul><ul><ul><li>IBM XML Master (Xmas) </li></ul></ul><ul><ul><li>Purple Technology XDB </li></ul></ul><ul><ul><li>Breeze XML Studio (v2) </li></ul></ul>
  47. 48. Adelard (Java-XML Data Binding) <ul><li>Java Standards Request 31 </li></ul><ul><li>Still vapor! (?) </li></ul>
  48. 49. Castor <ul><li>Implementation of JSR 31 </li></ul><ul><ul><li>http://castor.exolab.org </li></ul></ul><ul><li>Open-source </li></ul>
  49. 50. IBM XML Master (&quot;XMas&quot;) <ul><li>Not vaporware - it works!!! </li></ul><ul><li>Same idea as Java-XML Data Binding </li></ul><ul><li>From IBM Alphaworks </li></ul><ul><li>Two parts </li></ul><ul><ul><li>builder application </li></ul></ul><ul><ul><li>visual XML editor beans </li></ul></ul>
  50. 51. Brett McLaughlin's Data Binding Package <ul><li>See JavaWorld articles </li></ul>
  51. 52. Purple Technology XDB <ul><li>In progress (still vapor) </li></ul><ul><ul><li>Currently rewriting to use JDOM </li></ul></ul><ul><ul><li>JDOMBean helps </li></ul></ul><ul><li>Three parts </li></ul><ul><ul><li>XML utility classes </li></ul></ul><ul><ul><li>XML->Java data binding system </li></ul></ul><ul><ul><li>Caching filesystem-based XML database (with searching) </li></ul></ul>
  52. 53. Conclusion <ul><li>Java and XML are two great tastes that taste great together </li></ul>
  53. 54. Resources <ul><li>XML Developments: </li></ul><ul><ul><li>Elliot Rusty Harold: </li></ul></ul><ul><ul><ul><li>Café Con Leche - metalab.unc.edu/xml </li></ul></ul></ul><ul><ul><ul><li>Author, XML Bible </li></ul></ul></ul><ul><ul><li>Simon St. Laurent </li></ul></ul><ul><ul><ul><li>www.simonstl.com </li></ul></ul></ul><ul><ul><ul><li>Author, Building XML Applications </li></ul></ul></ul><ul><li>General </li></ul><ul><ul><li>www.xmlinfo.com </li></ul></ul><ul><ul><li>www.oasis-open.org/cover/xml.html </li></ul></ul><ul><ul><li>www.xml.com </li></ul></ul><ul><ul><li>www.jdm.com </li></ul></ul><ul><ul><li>www.purpletech.com/xml </li></ul></ul>
  54. 55. Resources: Java-XML Object Mapping <ul><li>JSR 31 </li></ul><ul><ul><li>http://java.sun.com/aboutJava/communityprocess/jsr/jsr_031_xmld.html </li></ul></ul><ul><ul><li>http://java.sun.com/xml/docs/binding/DataBinding.html </li></ul></ul><ul><li>XMas </li></ul><ul><ul><li>http://alphaworks.ibm.com/tech/xmas </li></ul></ul>
  55. 56. Resources <ul><li>XSL: </li></ul><ul><ul><li>James Tauber: </li></ul></ul><ul><ul><ul><li>xsl tutorial: www.xmlsoftware.com/articles/xsl-by-example.html </li></ul></ul></ul><ul><ul><li>Michael Kay </li></ul></ul><ul><ul><ul><li>Saxon </li></ul></ul></ul><ul><ul><ul><li>home.iclweb.com/icl2/mhkay/Saxon.html </li></ul></ul></ul><ul><ul><li>James Clark </li></ul></ul><ul><ul><ul><li>XP Parser, XT </li></ul></ul></ul><ul><ul><ul><li>editor, XSL Transformations W3C Spec </li></ul></ul></ul>
  56. 57. Resources: <ul><li>JDOM </li></ul><ul><ul><li>www.jdom.org </li></ul></ul>
  57. 58. Thanks To <ul><li>John McGann </li></ul><ul><li>Daniel Zen </li></ul><ul><li>David Orchard </li></ul><ul><li>My Mom </li></ul>

×