+ All Categories
Home > Documents > More XPATH and XSLT Xpath and Namespaces Xpath Programming in Java XSLT Default Rules XSLT...

More XPATH and XSLT Xpath and Namespaces Xpath Programming in Java XSLT Default Rules XSLT...

Date post: 22-Dec-2015
Category:
View: 270 times
Download: 0 times
Share this document with a friend
44
More XPATH and XSLT • Xpath and Namespaces • Xpath Programming in Java • XSLT Default Rules • XSLT Programming in Java
Transcript

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>[email protected]</ContactTo> </Author> <Author> <AuthorName>Steve DeRose</AuthorName> <ContactTo>[email protected]</ContactTo> </Author> </Book>

<Book> <PublishedDate>16 November 1999</PublishedDate> <Author> <AuthorName>James Clark</AuthorName> <ContactTo>[email protected]</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,[email protected]),

Author(authorName=Steve DeRose, [email protected])]),

Book(publishedDate=16 November 1999, authors=[Author(authorName=James Clark, [email protected])])]

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>[email protected]</email> </editor>

<editor> <name>Steve DeRose</name> <email>[email protected]</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>[email protected]</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, [email protected]), Author(authorName=Steve DeRose, [email protected])]),

Book(publishedDate=16 November 1999, authors=[Author(authorName=James Clark, [email protected])])]


Recommended