46-929 web technologies1 web technologies week four advanced dom and working with namespaces

51
46-929 Web Technologies 1 Web Technologies Week Four anced DOM and Working with namespa

Post on 21-Dec-2015

220 views

Category:

Documents


0 download

TRANSCRIPT

46-929 Web Technologies 1

Web Technologies

Week Four

Advanced DOM and Working with namespaces

46-929 Web Technologies 2

Notes on XML Namespaces

Namespace notes taken and adapted from “XML in a Nutshell”By Harold and Means

Java examples adapted from “XML and Java” – course text

Namespace specification is at:

http://www.w3.org/TR/REC-xml-names/

46-929 Web Technologies 3

Namespaces

Primary purpose:

To disambiguate element and attribute names.

Implementation:

• Attach a prefix to an element or attribute name.• Map the prefix to a URI. This need not be a real place.• Default URI’s may also be provided for those

elements with no prefix.• The URI’s partition the elements and attributes into

disjoint sets.

46-929 Web Technologies 4

Namespaces

• Each prefix is associated with one URI.• Names with prefixes associated with the same URI are in the same namespace.• Elements and attributes in namespaces have names with

exactly one colon. • The text before the colon is called the prefix.• The text after the colon is called the local part.• The complete name, including the colon, is called the qualified name.

46-929 Web Technologies 5

Namespaces

• Prefixes are bound to namespace URI’s by attaching an xmlns:prefix attribute to the the prefixed elementor one of its ancestors

For example:

<rdf:RDF xmlns:rdf=http://www.w3.org/TR/REC-rdf-syntax#>

associates the prefix rdf with the namespace URI shown. Thename RDF is therefore an element from this namespace.

46-929 Web Technologies 6

Namespaces

• Bindings have scope within the element in which they’redeclared and its contents.

<rdf:RDF xmlns:rdf=http://www.w3.org/TR/REC-rdf-syntax#>

<!– within this element the prefix rdf is associated with the RDF namespace

</rdf:RDF>

46-929 Web Technologies 7

Namespaces

The default namespace

• Is set using the xmlns attribute (with no prefix)• Applies only to elements not attributes

<SomeTag xmlns=“someURI”> <insideTag> … </insideTag> </SomeTag>

SomeTag and insideTag are both in the someURI namespace.

46-929 Web Technologies 8

Namespaces

If there is no default namespace is declared then tags without Prefixes are in no namespace at all. Not even the default one.

The only way an attribute belongs to a namespace is if it has a declared prefix.

<rdf:RDF xmlns:rdf=“http://www.w3.org/TR/REC-rdf-syntax#> <rdf:Description about=“someValue”> : </rdf:Description>

</rdf:RDF>

The about attribute isin no namespace.

46-929 Web Technologies 9

Declaring Namespaces

xmlns:pre=“someURN” is finexmlns:pre=“” is illegal

xmlns=“someURN” is finexmlns=“” legal and same as no namespace

46-929 Web Technologies 10

Some Examples From The W3C Specification

<x xmlns:edi='http://ecommerce.org/schema'>  <!-- the 'price' element's namespace is  http://ecommerce.org/schema -->  <edi:price units='Euro'>32.18</edi:price></x>

46-929 Web Technologies 11

<x xmlns:edi='http://ecommerce.org/schema'>  <!-- the 'taxClass' attribute's namespace is  http://ecommerce.org/schema -->  <lineItem edi:taxClass="exempt">Baby food</lineItem></x>

46-929 Web Technologies 12

<?xml version="1.0"?><!-- all elements here are explicitly in the HTML namespace --><html:html xmlns:html='http://www.w3.org/TR/REC-html40'>  <html:head><html:title>Frobnostication</html:title> </html:head>  <html:body><html:p>Moved to     <html:a href='http://frob.com'>here.</html:a></html:p> </html:body></html:html>

46-929 Web Technologies 13

<?xml version="1.0"?><!-- both namespace prefixes are available throughout --><bk:book xmlns:bk='urn:loc.gov:books'          xmlns:isbn='urn:ISBN:0-395-36341-6'>    <bk:title>Cheaper by the Dozen</bk:title>    <isbn:number>1568491379</isbn:number></bk:book>

46-929 Web Technologies 14

<?xml version="1.0"?><!-- elements are in the HTML namespace, in this case  by default --><html xmlns='http://www.w3.org/TR/REC-html40'>  <head><title>Frobnostication</title></head>  <body><p>Moved to     <a href='http://frob.com'>here</a>.</p></body></html>

46-929 Web Technologies 15

<?xml version="1.0"?><!-- unprefixed element types are from "books" --><book xmlns='urn:loc.gov:books'      xmlns:isbn='urn:ISBN:0-395-36341-6'>    <title>Cheaper by the Dozen</title>    <isbn:number>1568491379</isbn:number></book>

46-929 Web Technologies 16

<?xml version="1.0"?><!-- initially, the default namespace is "books" --><book xmlns='urn:loc.gov:books'      xmlns:isbn='urn:ISBN:0-395-36341-6'>    <title>Cheaper by the Dozen</title>    <isbn:number>1568491379</isbn:number>    <notes>      <!-- make HTML the default namespace for  some commentary -->      <p xmlns='urn:w3-org-ns:HTML'>          This is a <i>funny</i> book!      </p>    </notes></book>

46-929 Web Technologies 17

<?xml version='1.0'?><Beers>  <!-- the default namespace is now that of HTML -->  <table xmlns='http://www.w3.org/TR/REC-html40'>   <th><td>Name</td><td>Origin</td><td>Description</td></th>   <tr>      <!-- no default namespace inside table cells -->     <td><brandName xmlns="">Huntsman</brandName></td>     <td><origin xmlns="">Bath, UK</origin></td>     <td>       <details xmlns=""><class>Bitter</class><hop>Fuggles</hop>         <pro>Wonderful hop, light alcohol, good summer beer</pro>         <con>Fragile; excessive variance pub to pub</con>         </details>        </td>      </tr>    </table>  </Beers>

The default namespace can be set to the empty string. This has the same effect, within the scopeof the declaration, of there being no default namespace.

46-929 Web Technologies 18

<!-- http://www.w3.org is bound to n1 and n2 --><x xmlns:n1="http://www.w3.org"     xmlns:n2="http://www.w3.org" >  <bad a="1"     a="2" />  <bad n1:a="1"  n2:a="2" /></x>

46-929 Web Technologies 19

<!-- http://www.w3.org is bound to n1 and is the default --><x xmlns:n1="http://www.w3.org"     xmlns="http://www.w3.org" >   <good a="1"     b="2" />   <good a="1"     n1:a="2" /></x>

46-929 Web Technologies 20

Namespaces and Java

// Exploring the NamespaceCorrector class in Chapter 4 of// XML and Java

// Example 1

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.Document;import org.w3c.dom.Element;import org.w3c.dom.Text;

46-929 Web Technologies 21

public class NamespaceExplore {

static final String NS = "http://www.andrew.cmu.edu/~mm6"; // the assigned namespace to the xml:lang attribute static final String XML_NS = "http://www.w3.org/XML/1998/namespace";

// the assigned namespace of the xmlns attribute static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/";

46-929 Web Technologies 22

public static void main(String[] argv) throws Exception {

DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); dbfactory.setNamespaceAware(true); DocumentBuilder builder = dbfactory.newDocumentBuilder(); Document factory = builder.newDocument(); OutputFormat format = new OutputFormat("xml", "UTF-8", true); XMLSerializer serializer = new XMLSerializer(System.out, format);

// build a top element within a namespace Element top = factory.createElementNS(NS, "mm6:GradeBook");

46-929 Web Technologies 23

// define an xmlns attribute within this top element top.setAttributeNS(XMLNS_NS, "xmlns:mm6", NS);

// define an xml:lang attribute within this top element top.setAttributeNS(XML_NS, "xml:lang", "en");

Element student = factory.createElementNS(NS,"mm6:Student"); top.appendChild(student);

Text t = factory.createTextNode("87.5"); student.appendChild(t);

serializer.serialize(top); System.out.println(""); }}

46-929 Web Technologies 24

D:\McCarthy\www\95-733\examples\chap04>java NamespaceExplore

<?xml version="1.0" encoding="UTF-8"?><mm6:GradeBook xml:lang="en" xmlns:mm6= "http://www.andrew.cmu.edu/~mm6"> <mm6:Student>87.5</mm6:Student></mm6:GradeBook>

Output

46-929 Web Technologies 25

Attributes and Namespaces// Exploring the NamespaceCorrector class in Chapter 4 of// XML and Java

// Example 2 Looking at Attributes

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.Document;import org.w3c.dom.Element;import org.w3c.dom.Text;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Attr;

46-929 Web Technologies 26

public class NamespaceExplore2 {

static final String NS = "http://www.andrew.cmu.edu/~mm6"; // the assigned namespace to the xml:lang attribute static final String XML_NS = "http://www.w3.org/XML/1998/namespace";

// the assigned namespace of the xmlns attribute static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/";

Same as before

46-929 Web Technologies 27

public static void main(String[] argv) throws Exception {

DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); dbfactory.setNamespaceAware(true); DocumentBuilder builder = dbfactory.newDocumentBuilder(); Document factory = builder.newDocument(); OutputFormat format = new OutputFormat("xml", "UTF-8", true); XMLSerializer serializer = new XMLSerializer(System.out, format);

Same as before

46-929 Web Technologies 28

// build a top element within a namespace Element top = factory.createElementNS(NS, "mm6:GradeBook");

// define an xmlns attribute within this top element top.setAttributeNS(XMLNS_NS, "xmlns:mm6", NS);

// define an xml:lang attribute withing this top element top.setAttributeNS(XML_NS, "xml:lang", "en");

// create a Student tag Element student = factory.createElementNS(NS,"mm6:Student"); // add a prefixed attribute to Student student.setAttributeNS(NS,"mm6:StudentID", "123-34-8765");

top.appendChild(student);We are creating attributes withnamespaces.

46-929 Web Technologies 29

Text t = factory.createTextNode("87.5"); student.appendChild(t);

serializer.serialize(top); System.out.println("");

// display the attributes in the student tag showNamespaceOfAttributes(student);

// display the attributes in the top tag

showNamespaceOfAttributes(top); }

46-929 Web Technologies 30

public static void showNamespaceOfAttributes(Element e) {

System.out.println("Display attributes of " + e.getTagName()); NamedNodeMap map = e.getAttributes(); for (int i = 0; i < map.getLength(); i++) { Attr attr = (Attr)map.item(i); String prefix = attr.getPrefix(); String name = attr.getName(); String val = attr.getValue(); String uri = attr.getNamespaceURI(); System.out.println("Attribute ====>" + name); System.out.println(" prefix =" + prefix); System.out.println(" value = " + val); System.out.println(" NS URI = " + uri); }

}}

46-929 Web Technologies 31

OutputD:\McCarthy\www\95-733\examples\chap04>java NamespaceExplore2<?xml version="1.0" encoding="UTF-8"?><mm6:GradeBook xml:lang="en“ xmlns:mm6="http://www.andrew.cmu.edu/~mm6"> <mm6:Student mm6:StudentID="123-34-8765">87.5 </mm6:Student></mm6:GradeBook>

Display attributes of mm6:StudentAttribute ====>mm6:StudentID prefix =mm6 value = 123-34-8765 NS URI = http://www.andrew.cmu.edu/~mm6

46-929 Web Technologies 32

Display attributes of mm6:GradeBookAttribute ====>xml:lang prefix =xml value = en NS URI = http://www.w3.org/XML/1998/namespaceAttribute ====>xmlns:mm6 prefix =xmlns value = http://www.andrew.cmu.edu/~mm6 NS URI = http://www.w3.org/2000/xmlns/

46-929 Web Technologies 33

NCTest.java – XML and Java

// NCTest.java Listing 4.2 XML and Java

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.Document;import org.w3c.dom.Element;

46-929 Web Technologies 34

public class NCTest { static final String NS0 = "http://example.com/@"; static final String NS1 = "http://example.com/a"; static final String XML_NS = "http://www.w3.org/XML/1998/namespace";

static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/";

public static void main(String[] argv) throws Exception { DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); dbfactory.setNamespaceAware(true); DocumentBuilder builder = dbfactory.newDocumentBuilder(); Document factory = builder.newDocument(); OutputFormat format = new OutputFormat("xml", "UTF-8", true); XMLSerializer serializer = new XMLSerializer(System.out, format);

46-929 Web Technologies 35

Element top = factory.createElementNS(null, "Address"); top.setAttributeNS(XMLNS_NS, "xmlns:p", NS0);

// Add an element that has the namespace and no prefix. Element el1 = factory.createElementNS(NS1, "Zip"); // el1 has an attribute of which namespace is // the same as el1. el1.setAttributeNS(NS1, "p:id", ""); el1.appendChild(factory.createElementNS(null, "Zip2")); top.appendChild(el1);

// Add an element that has the namespace and prefix. Element el2 = factory.createElementNS(NS1, "p:State"); // add an attribute to el2 -- code deleted -- no harm mistake in book el2.setAttributeNS(XML_NS, "xml:lang", "en"); top.appendChild(el2);

46-929 Web Technologies 36

Element el3 = factory.createElementNS(NS0, "p:City"); top.appendChild(el3);

// Prints the tree before correction. serializer.serialize(top); System.out.println("");

// Correct NamespaceCorrector.correct(top); // Prints the tree after correction. serializer.reset(); serializer.serialize(top); System.out.println("");

What does the output document look like?

Now, what does theoutput document look like?

46-929 Web Technologies 37

// Another test: // p:Country and p:iso2 have the same prefix but // different namespaces. Element el4 = factory.createElementNS(NS0, "p:Country"); el4.setAttributeNS(NS1, "p:iso2", "ja"); // This should throw an exception. NamespaceCorrector.correct(el4); }}

What does this documentlook like and whycan’t it be repaired?

46-929 Web Technologies 38

D:\McCarthy\www\95-733\examples\chap04>javac NCTest.java

D:\McCarthy\www\95-733\examples\chap04>java NCTest

<?xml version="1.0" encoding="UTF-8"?><Address xmlns:p="http://example.com/@"> <Zip p:id=""> <Zip2/> </Zip> <p:State xml:lang="en"/> <p:City/></Address>

This is not as the authorintended.

46-929 Web Technologies 39

<?xml version="1.0" encoding="UTF-8"?><Address xmlns:p="http://example.com/@"> <Zip p:id="" xmlns="http://example.com/a" xmlns:p="http://example.com/a"> <Zip2 xmlns=""/> </Zip> <p:State xml:lang="en" xmlns:p="http://example.com/a"/> <p:City/></Address>

Corrected document.

46-929 Web Technologies 40

Exception in thread "main" org.w3c.dom.DOMException: Namespace inconsistence at NamespaceCorrector.set(NamespaceCorrector.java:89) at NamespaceCorrector.correctElement(NamespaceCorrector.java:78) at NamespaceCorrector.correct(NamespaceCorrector.java:26) at NCTest.main(NCTest.java:67)

Too bad to fix.

46-929 Web Technologies 41

NamespaceCorrector.java // NamespaceCorrector.java

import org.w3c.dom.Attr;import org.w3c.dom.DOMException;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NamedNodeMap;

46-929 Web Technologies 42

/** * Add required namespace declarations. */public class NamespaceCorrector { private static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/";

private NamespaceCorrector() { }

46-929 Web Technologies 43

/** @param node The top node of target nodes */

public static void correct(Node node) { switch (node.getNodeType()) { case Node.ELEMENT_NODE: correctElement((Element)node); // Fall down case Node.DOCUMENT_NODE: case Node.DOCUMENT_FRAGMENT_NODE: case Node.ENTITY_REFERENCE_NODE: for (Node ch = node.getFirstChild(); ch != null; ch = ch.getNextSibling()) { correct(ch); } break; } }

46-929 Web Technologies 44

/** * Check whether the prefixes and the namespaces of el and * its attributes are declared or not. * if not, add a namespace declaration to el. */ private static void correctElement(Element el) { // Check el. String prefix = el.getPrefix(); String current = el.getNamespaceURI(); String declared = howDeclared(el, prefix);

46-929 Web Technologies 45

if (prefix == null) { if (current == null && declared == null) { // ok } else if (current == null || declared == null) { set(el, prefix, current == null ? "" : current); } else if (!current.equals(declared)) { set(el, prefix, current); }} else { if (current == null) throw new DOMException( DOMException.NAMESPACE_ERR, el.getNodeName() +" has no namespace"); if (declared == null || !current.equals(declared)) set(el, prefix, current); }

46-929 Web Technologies 46

// Check attributes of el. NamedNodeMap map = el.getAttributes(); for (int i = 0; i < map.getLength(); i++) { Attr attr = (Attr)map.item(i); prefix = attr.getPrefix(); if (prefix == null || prefix.equals("xml") || prefix.equals("xmlns")) continue; current = attr.getNamespaceURI(); declared = howDeclared(el, prefix); if (declared == null || !current.equals(declared)) { set(el, prefix, current); i = -1; // map has changed. // So restart the loop. } } }

46-929 Web Technologies 47

private static void set(Element el, String prefix, String ns) { String qname = prefix == null ? "xmlns" : "xmlns:"+prefix;

if (el.getAttributeNode(qname) != null) throw new DOMException(DOMException.NAMESPACE_ERR, "Namespace inconsistence"); el.setAttributeNS(XMLNS_NS, qname, ns); }

46-929 Web Technologies 48

/** * Search <var>context</var> and ancestors for declaration * of prefix. * @param prefix Prefix, or <code>null</code> for default ns. */ private static String howDeclared(Element context, String prefix) { String qname = prefix == null ? "xmlns" : "xmlns:"+prefix;

46-929 Web Technologies 49

for (Node node = context; node != null; node = node.getParentNode()) { if (node.getNodeType() == Node.ELEMENT_NODE) { Attr attr = ((Element)node).getAttributeNode(qname); if (attr != null) { if (prefix == null && attr.getNodeValue().equals("")) return null; else return attr.getNodeValue(); } } } return null; }}

46-929 Web Technologies 50

Homework

Trace the NamespaceCorrector.java program for the following cases: Case 1:

An element has a namespace but no prefix. An ancestorof the element has a default namespace with the same namespace value.

Case 2: An element has a namespace but no prefix and no

default namespace exists.

46-929 Web Technologies 51

Case 3.An element has a namespace but no prefix and anancestor has a different default namespace.

Case 4.An element has a namespace but no prefix andthis element declares a different default namespace.

Case 5.An element has a namespace and a prefixthat points to a different namespace.