View
271
Download
0
Category
Preview:
Citation preview
More XPATH and XSLT
• Xpath and Namespaces
• Xpath Programming in Java
• XSLT Default Rules
• XSLT Programming in Java
Xpath and Namespaces
• Namespaces are widely used
• In a SOAP message, for example, every element is qualified with a namespace
• Here we will look at how namespaces are handled in XPath
Xpath and Namespaces
Consider an Xpath expression
/Envelope/Header/Signature
Now, with namespaces included
/SOAP-ENV:Envelope/SOAP-ENV:Header/dsig:Signature
What is wrong with this approach?
Namespace prefixes may vary. SE:Envelope is a legal SOAP element if the prefix SE is associated with
http://schemas.xmlsoap.org/soap/envelope
Xpath and Namespaces
Suppose we want to select all the Signature elementsassociated with the namespace http://www.w3.org/2000/09/xmldsig#
Write the Xpath expression as follows
//*[namespace-uri()=“http://www.w3.org/2000/09/xmldsig#” and local-name() = “Signature”]
Xpath Programming in Java
• We can evaluate an Xpath expression from within a Java program.
• The following is an example using Namespaces.
XPathTest.java<?xml version="1.0" encoding="UTF-8"?><Signature Id="MyFirstSignature" xmlns= "http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm= "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <SignatureMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#dsa-sha1"/> <Reference URI= "http://www.w3.org/TR/2000/REC-xhtml1-20000126/"> <Transforms> <Transform Algorithm= "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> </Transforms>
<DigestMethod Algorithm= "http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>j6lwx3rvEPO0vKtMup4NbeVu8nk= </DigestValue> </Reference> </SignedInfo>
XPathTest.java
// XML and Java Second Ed. Chapter 7// For JAXPimport javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.xml.sax.InputSource;
// For Xalan XPath APIimport org.apache.xpath.XPathAPI;import org.w3c.dom.traversal.NodeIterator; import org.w3c.dom.Node;import org.w3c.dom.Document;
public class XPathTest { public static void main(String[] args) throws Exception { String xmlFilePath = args[0]; String xPath = args[1];
System.out.println("Input XML File: " + xmlFilePath); System.out.println("XPath: " + xPath);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder parser = factory.newDocumentBuilder();
InputSource in = new InputSource(xmlFilePath); Document doc = parser.parse(in);
Node contextNode = doc.getDocumentElement(); NodeIterator i = XPathAPI.selectNodeIterator(contextNode, xPath); int count = 0; Node node; // For each node while ((node = i.nextNode()) != null) { // Outputs the node to System.out System.out.println(node.toString()); count++; } System.out.println("" + count + " match(es)"); }}
Example RunD:\McCarthy\www\95-733\examples\xpath\HandleNamespaces>java XPathTest MyFirstSignature.xml "//*[local-name()='DigestValue' and namespace-uri()='http://www.w3.org/2000/09/xmldsig#']“
Input XML File: MyFirstSignature.xmlXPath: //*[local-name()='DigestValue' and namespace-uri()='http://www.w3.org/2000/09/xmldsig#']
<DigestValue>j6lwx3rvEPO0vKtMup4NbeVu8nk=</DigestValue>1 match(es)
XSLT Default Rules
<xsl:template match-”*|/”> <xsl:apply-templates></xsl:template>
<xsl:template match=“text() | @*”> <xsl:value-of select=“.”/></xsl:template>
<xsl:template match=“processing-instruction() | comment()” />
XSLT Programming in Java
Two important interfaces to represent the XML and XSLTdocuments:
javax.xml.transform
Interface Source All Known Implementing Classes:
DOMSource, SAXSource, StreamSource
javax.xml.transform Interface Result All Known Implementing Classes: DOMResult, SAXResult, StreamResult
XSLT Programming in JavaA Factory to build XSLT Transformers
javax.xml.transform
Class TransformerFactory
Ask for a Transformer with an associated XSLT document:
Transformer t = newTransformer(Source source)
Use t to do the transformation
voidtransform(Source xmlSource, Result outputTarget) Process the source tree to the output result.
XSLT Stream to Stream Example
// XML and Java Chapter 7import javax.xml.transform.TransformerFactory;import javax.xml.transform.Transformer;import javax.xml.transform.stream.StreamSource;import javax.xml.transform.stream.StreamResult;
public class XSLTStreamTest { public static void main(String[] args) throws Exception { // args[0] specifies the path to the input XSLT stylesheet String xsltURL = args[0]; // args[1] specifies the path to the input XML document String xmlURL = args[1];
// Creates instances of StreamSource for the stylesheet StreamSource xslt = new StreamSource(xsltURL); // Creates instances of StreamSource for the input document StreamSource xml = new StreamSource(xmlURL);
// Creates an instance of TransformerFactory TransformerFactory factory = TransformerFactory.newInstance(); // Creates an instance of Transformer Transformer transformer = factory.newTransformer(xslt); // Executes the Transformer transformer.transform(xml, new StreamResult(System.out)); }}
XSLT DOM to DOM Example// XML and Java Chapter 7import javax.xml.transform.TransformerFactory;import javax.xml.transform.Transformer;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.dom.DOMResult;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.apache.xml.serialize.OutputFormat;import org.apache.xml.serialize.XMLSerializer;import org.w3c.dom.Node;import org.w3c.dom.Element;import org.w3c.dom.Document;import org.w3c.dom.DocumentFragment;
public class XSLTDOMTest { public static void main(String[] args) throws Exception { // args[0] specifies the path to the input XSLT stylesheet String xsltURL = args[0]; // args[1] specifies the path to the input XML document String xmlURL = args[1];
// Creates an instance of DocumentBuilderFactory. DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); dFactory.setNamespaceAware(true); // Creates an instance of DocumentBuilder DocumentBuilder parser = dFactory.newDocumentBuilder();
// Creates a DOM instance of the stylesheet Document xsltDoc = parser.parse(xsltURL); // Creates a DOM instance of the input document Document xmlDoc = parser.parse(xmlURL);
// Creates an instance of TransformerFactory TransformerFactory tFactory = TransformerFactory.newInstance(); // Checks if the factory supports DOM or not if(!tFactory.getFeature(DOMSource.FEATURE) || !tFactory.getFeature(DOMResult.FEATURE)) throw new Exception("DOM is not supported");
// Creates instances of DOMSource and DOMResult DOMSource xsltDOMSource = new DOMSource(xsltDoc); DOMSource xmlDOMSource = new DOMSource(xmlDoc); DOMResult domResult = new DOMResult();
// Creates an instance of Transformer Transformer transformer = tFactory.newTransformer(xsltDOMSource);
// Executes the Transformer transformer.transform(xmlDOMSource, domResult);
// Gets the result Node resultNode = domResult.getNode();
// Prints the response OutputFormat formatter = new OutputFormat(); formatter.setPreserveSpace(true); XMLSerializer serializer = new XMLSerializer(System.out, formatter); switch (resultNode.getNodeType()) { case Node.DOCUMENT_NODE: serializer.serialize((Document)resultNode); break; case Node.ELEMENT_NODE: serializer.serialize((Element)resultNode); break; case Node.DOCUMENT_FRAGMENT_NODE: serializer.serialize((DocumentFragment)resultNode); break; default: throw new Exception("Unexpected node type"); }}}
SAX Event Translation Using XSLT
Suppose we have a SAX handler written for a particulartype of XML document.
Suppose too that we have a new document with similarsemantics but with a different structure.
We don’t want to modify our old handler. Instead we wantto do a translation of the new document to the old format.
XML and Java, Second Edition, Developing Web Applications, Hiroshi Maruyama, et.al. 2002
SAX Parser
ContentHandler
SAXResult
ContentHandler
TransformInput XML
JAXP/SAX : :
SAX::
JAXP/SAX : :
SAX Events SAX Events
TransformerHandlerSAXParser
SAX::
Application
(2)Register
(3)Register
Register(1)
(4) (5) (6) (7)
XSLT
Books.xml<?xml version="1.0" encoding="UTF-8"?><Books xmlns="http://www.example.com/xmlbook2/chap07/"> <Book> <PublishedDate>16 November 1999</PublishedDate> <Author> <AuthorName>James Clark</AuthorName> <ContactTo>jjc@jclark.com</ContactTo> </Author> <Author> <AuthorName>Steve DeRose</AuthorName> <ContactTo>Steven_DeRose@Brown.edu</ContactTo> </Author> </Book>
<Book> <PublishedDate>16 November 1999</PublishedDate> <Author> <AuthorName>James Clark</AuthorName> <ContactTo>jjc@jclark.com</ContactTo> </Author> </Book></Books>
We have a handler for Books.xml// Adapted from XML and Java Chapter 7import java.util.Vector;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;
// Imports for main() to test the Handler
import org.xml.sax.InputSource;import org.xml.sax.XMLReader;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;
public class BookHandler extends DefaultHandler { // An array to store the results final Vector books; public BookHandler() { this.books = new Vector(); }
// Instance variables temporarily used for processing Book currentBook = null; Author currentAuthor = null; StringBuffer buf = new StringBuffer();
class Book { String publishedDate; Vector authors = new Vector(); public String toString() { return ("Book(publishedDate=" + publishedDate + ", authors=" + authors+")"); } } class Author { String authorName; String contactTo; public String toString() { return ("Author(authorName=" + authorName + ", contactTo=" + contactTo + ")"); } }
public void endDocument() throws SAXException { System.out.println(books); }
public void startElement(String uri,String localName, String qName, Attributes attributes) throws SAXException { if ("Book".equals(qName)) { currentBook = new Book(); return; }
if ("Author".equals(qName)) { currentAuthor = new Author(); return; } buf.setLength(0); }
public void endElement(String uri, String localName, String qName) throws SAXException { if ("Book".equals(qName)) { books.addElement(currentBook); return; }
if ("Author".equals(qName)) { currentBook.authors.addElement(currentAuthor); return; } if ("PublishedDate".equals(qName)) currentBook.publishedDate = buf.toString(); else if ("AuthorName".equals(qName)) currentAuthor.authorName = buf.toString(); else if ("ContactTo".equals(qName)) currentAuthor.contactTo = buf.toString(); buf.setLength(0); }
public void characters(char[] ch, int start, int length) throws SAXException { buf.append(new String(ch, start, length)); }
public static void main(String args[]) throws Exception {
// Create and InputSource on a book.xml document InputSource xml = new InputSource(args[0]); // Creates a SAX parser SAXParserFactory pFactory = SAXParserFactory.newInstance(); SAXParser parser = pFactory.newSAXParser(); XMLReader xmlReader = parser.getXMLReader();
// Set up this class as the handler xmlReader.setContentHandler(new BookHandler()); // Parses the input XML (which is of the appropriate form) xmlReader.parse(xml);
}}
D:..\examples\XSLTFilter> java BookHandler Books.xml
[Book(publishedDate=16 November 1999, authors=[Author(authorName=James Clark,contactTo=jjc@jclark.com),
Author(authorName=Steve DeRose, contactTo=Steven_DeRose@Brown.edu)]),
Book(publishedDate=16 November 1999, authors=[Author(authorName=James Clark, contactTo=jjc@jclark.com)])]
But no handler for sample.xml…<?xml version="1.0" encoding="UTF-8"?><W3Cspecs xmlns="http://www.example.com/xmlbook2/chap07/"> <spec title="XML Path Language (XPath) Version 1.0" url="http://www.w3.org/TR/xpath"> <date type="REC">16 November 1999</date> <editors> <editor> <name>James Clark</name> <email>jjc@jclark.com</email> </editor>
<editor> <name>Steve DeRose</name> <email>Steven_DeRose@Brown.edu</email> </editor> </editors> </spec> <spec title="XSL Transformations (XSLT) Version 1.0" url="http://www.w3.org/TR/xslt"> <date type="REC">16 November 1999</date> <editors> <editor> <name>James Clark</name> <email>jjc@jclark.com</email> </editor> </editors> </spec></W3Cspecs>
We write an XSLT program…<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.example.com/xmlbook2/chap07/"> <xsl:output method="xml" encoding="UTF-8"/>
<xsl:template match="*[local-name()='W3Cspecs']"> <Books><xsl:apply-templates/></Books> </xsl:template>
<xsl:template match="*[local-name()='spec']"> <Book><xsl:apply-templates/></Book> </xsl:template>
<xsl:template match="*[local-name()='date']"> <PublishedDate><xsl:apply-templates/></PublishedDate> </xsl:template>
<xsl:template match="*[local-name()='editor']"> <Author><xsl:apply-templates/></Author> </xsl:template>
<xsl:template match="*[local-name()='name']"> <AuthorName><xsl:apply-templates/></AuthorName> </xsl:template>
<xsl:template match="*[local-name()='email']"> <ContactTo><xsl:apply-templates/></ContactTo> </xsl:template>
<xsl:template match="@*"> <xsl:value-of select="name()"/>=<xsl:value-of select="."/> </xsl:template></xsl:stylesheet>
In book but no need.
And write a program to pipe the XSLT output to
BookHandler.javaimport javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import javax.xml.transform.TransformerFactory;import javax.xml.transform.sax.SAXSource;import javax.xml.transform.sax.SAXResult;import javax.xml.transform.sax.SAXTransformerFactory;import javax.xml.transform.sax.TransformerHandler;import javax.xml.transform.stream.StreamSource;import org.xml.sax.InputSource;import org.xml.sax.XMLReader;
public class XSLTSAXTest {
public static void main(String[] args) throws Exception { // args[0] specifies the URI for the XSLT stylesheet String xsltURL = args[0]; // args[1] specifies the URI for the input XML document String xmlURL = args[1];
// Creates a stream source for the stylesheet StreamSource xslt = new StreamSource(xsltURL); // Creates an input source for the input document InputSource xml = new InputSource(xmlURL);
// Creates a SAX parser SAXParserFactory pFactory = SAXParserFactory.newInstance(); pFactory.setNamespaceAware(true); SAXParser parser = pFactory.newSAXParser(); XMLReader xmlReader = parser.getXMLReader();
// Creates an instance of TransformerFactory TransformerFactory tFactory = TransformerFactory.newInstance();
// Checks if the TransformingFactory supports SAX or not if (!tFactory.getFeature(SAXSource.FEATURE)) throw new Exception("SAX is not supported");
// Casts TransformerFactory to SAXTransformerFactory SAXTransformerFactory stFactory = ((SAXTransformerFactory)tFactory); // Creates a TransformerHandler with the stylesheet TransformerHandler tHandler = stFactory.newTransformerHandler(xslt); // Sets the TransformerHandler to the SAXParser xmlReader.setContentHandler(tHandler); // Sets the application ContentHandler // to the TransformerHandler tHandler.setResult(new SAXResult(new BookHandler()));
// Parses the input XML xmlReader.parse(xml); }}
D:..\examples\XSLTSAXFilter>java XSLTSAXTest sample-4.xsl sample.xml
[Book(publishedDate=16 November 1999, authors=[Author(authorName=James Clark, contactTo=jjc@jclark.com), Author(authorName=Steve DeRose, contactTo=Steven_DeRose@Brown.edu)]),
Book(publishedDate=16 November 1999, authors=[Author(authorName=James Clark, contactTo=jjc@jclark.com)])]
Recommended