View
222
Download
0
Embed Size (px)
Citation preview
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.