Cheap Web Hosting for Developers

PHP, MySQL, Java, Unix Cheap Web Hosting

208 CHAPTER 6 DOCUMENT OBJECT MODEL (DOM)

Filed under: PHP and XML — webmaster @ 12:25

208 CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) attributes with values using the factory methods. The only parameter is a name (or in the case of using namespaces, a namespace URI and a name): /* Equivalent methods for creation of lang attribute */ $lang = $dom->createAttribute(”lang”); $lang = $dom->createAttributeNS(NULL, “lang”); Both of these lines of code result in the creation of a DOMAttr object named lang. Using these methods, you need to specify a value, which you can do using the nodeValue property from the DOMNodeclass or using the value property from the DOMAttr class: /* Equivalent calls to set the value for the lang attribute to “en” */ $lang->nodeValue = “en”; $lang->value = “en”; You can also create attributes with values at the same time using the new keyword. Again, these nodes will not be associated with a document: $lang = new DOMAttr(”lang”, “en”); Using any of these methods to create an attribute requires the attribute to be inserted into the tree. Using methods already covered, you could add it doing this: /* Equivalent methods for inserting an attribute */ $bookinfo->appendChild($lang); $bookinfo->insertBefore($lang, NULL); The last method uses insertBefore()with the reference node parameter being NULL. When NULLis passed as the reference node, the function works in the same way as appendChild(). The node is inserted as the last node. Note Attributes are not children of element nodes. When using the appending child functions, such as appendChild(), the attribute is not appended as a child but instead appended in the attribute property list of the element. You can also add attribute nodes using the setAttributeNode() and setAttributeNodeNS() methods from the DOMElement class. These methods take a single DOMAttr object as a parameter. These methods will first check whether an attribute with the same name and in the case of setAttributeNodeNS(), the same name and namespace exists. Then, if it exists, these methods remove the attribute and replace it with the new attribute. These methods return NULL if no attribute was replaced or return the replaced attribute. For example: /* Equivalent calls for this document as no namespaces are being used */ $oldlang = $bookinfo->setAttributeNode($lang); $oldlang = $bookinfo->setAttributeNodeNS($lang); You can also create attributes without ever having to directly create a DOMAttrobject. The DOMElement class includes the methods setAttribute() and setAttributeNS(). These methods

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost PHP Web Hosting services

PHP, MySQL, Java, Unix Cheap Web Hosting

CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) 207

Filed under: PHP and XML — webmaster @ 00:26

CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) 207 the tree and automatically be associated with the document. In cases where the current node is not associated with a document, a no modification allowed error is issued, because these nodes are read-only. Before appending the author element, $biauthor, into the tree, you can append the firstname and surnamenodes to the author element. Remember, $biauthor was created with an association to the document, so the firstname and surname elements, once appended, will inherit this association: $biauthor->appendChild($surname); $biauthor->insertBefore($firstname, $surname); The first line should look familiar because it was used to append the bookinfo element. The second line uses a new method, insertBefore(). It works similarly to appendChild(), but the second argument, which must be a child node of the current node, is used as a reference point to insert the new node before. This code is the same as writing the following: $biauthor->appendChild($firstname); $biauthor->appendChild($surname); You will typically use insertBefore() when trying to insert elements in the middle of a list of child nodes, but it s used in the example to show how it works. With the author element complete with content, you can now insert it into the document: $bookinfo->appendChild($biauthor); If you look at the output now, you will see the document beginning to take shape. The document may look odd because it is all strung together without any line feeds, so you can beautify the output using the formatOutputproperty: $dom->formatOutput = TRUE; print $dom->saveXML(); Well, it looks like the title element was omitted and needs to be inserted. In this case, insertBefore() is definitely appropriate. The titlenode is supposed to come before the author element, which is already in the tree: $bookinfo->insertBefore($bititle, $biauthor); You can deal with the remainder of the elements for the tree later because you already have enough information to create them. For now, you ll move on to dealing with attribute nodes. Attribute Nodes You can handle attribute nodes, as well as specific attribute functionality from the DOMElement class, in a similar fashion to element nodes. You can create them using factory methods from the DOMDocumentclass by directly instantiating them, and you can create them using methods from a DOMElement object. You can also insert and remove them using the methods from the DOMNode class as well as methods from a DOMElement object. Equivalent methods for attribute creation exist for a DOMDocumentobject as for element creation. Currently (though this may change in future version of PHP), you cannot create

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Clan Web Hosting services

PHP, MySQL, Java, Unix Cheap Web Hosting

206 CHAPTER 6 DOCUMENT OBJECT MODEL (DOM)

Filed under: PHP and XML — webmaster @ 14:16

206 CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) These two new elements, unlike the previous created elements, are not associated with a document and are read-only. Until they are associated with a document, they can be inserted into a tree, but no children, other than any text nodes that may have been created during instantiation, can be appended to these elements. When creating elements, you have a possibility of a DOMException being thrown. The name of the element is checked to ensure that it is valid. In the event the check fails, the object is not created and a DOMException indicating that invalid characters were used may be thrown. For example, the name 123 is used when trying to instantiate a DOMElementobject: try { $test = new DOMElement(”123″); } catch (DOMException $e) { var_dump($e); } According to the XML specification, names cannot start with a numeric, which results in a DOMException being thrown. As previously mentioned, the constructor can take a third parameter indicating the URI for the namespace of the element. When this is passed, the first argument, being a qualified name, will split the name parameter into any prefix and local name values. Without the third parameter being used, the name passed is used as the local name even if it contains a colon: $nsElement = new DOMElement(”nse:myelement”, NULL, “http://www.example.com/ns”); This instantiates a DOMElement object with the myelement element prefixed with nse and living in the http://www.example.com/ns namespace. A value can be passed for the content, but in this case, NULL is passed, and the element is created without any children. Inserting Elements With a few elements currently created, they need to be inserted into the tree. The methods for appending and inserting nodes come from the DOMNode class and thus are not specific to element nodes; in other words, they can be called from other node types as well. Currently, the document contains only a single document element. Using the document node, $dom, the document element will be retrieved and the bookinfo element appended: $dom->documentElement->appendChild($bookinfo); The appendChild() method takes a node to be appended as a child of the current node for a parameter and returns the node appended. The node is appended as the last child of the current node s children. In this case, the book element currently has no children, so the bookinfo is added as the first child. Also, you already have a handle on the node being inserted, so you have no need to capture the return value. This method, like the other insertion methods, may throw a DOMException. The possible cases for an exception are a hierarchy error, when the node being appended already exists in the tree and is a parent of the current node; a wrong document error, when the node being appended is associated with a document other than the current nodes document; and lastly a no modification allowed error, when the current node is read-only. One point to note about a hierarchy error is that it is not considered an error to append a node without an associated document to a node with a document because the appended node will become part of

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Cheap Web Hosting services

PHP, MySQL, Java, Unix Cheap Web Hosting

CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) 205

Filed under: PHP and XML — webmaster @ 03:20

CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) 205 point contains a DTD and the document element node book. Ignoring the attribute for now, the next node to be created is the bookinfo element, which is the first child element of book. For example: $bookinfo = $dom->createElement(”bookinfo”); This piece of code returns a DOMElement object, $bookinfo, with the name bookinfo. The createElement method takes one mandatory parameter and one optional parameter. The first parameter is the qualified name of the element to be created, which in this case is bookinfo. The second optional parameter is the value of the element. In the event the element node will contain text content, you can do this at the same time the element is created. In actuality, a text node is created and appended as a child of the element being created. For instance, the first child of the bookinfo element is a title element, consisting of only text: $bititle = $dom->createElement(”title”, “DOM in PHP 5″); With these two lines of code, you have created two new objects. The variable $bookinfo holds the DOMElement object for the bookinfo node, and the variable $bititle holds the DOMElement object for a titlenode. This $bititle node also has a child text node, with the contents DOM in PHP 5. For now they exist as stand-alone nodes. They are associated with the current document but are not within the tree at this point. Before inserting these nodes, it is helpful to look at other ways to create element nodes. You can also create elements within a namespace. The document being created here does not use namespaces, but you could still use the createElementNS() method: $biauthor = $dom->createElementNS(NULL, “author”); This method requires two mandatory parameters and accepts a third parameter, which is an optional value parameter. The first parameter is the namespace URI. In this case, nodes are not within any namespace, so NULL is passed. The second parameter is the qualified name of the element. As you probably recall, this consists of the prefix and the local name. For example, you could create an element named trash in the http://www.example.com/trash namespace. The prefix tr will also be associated with this element: $trash = $dom->createElementNS(”http://www.example.com/trash”, “tr:trash”); When the $trash object is inserted into a tree, the element will be associated with the prefix, and if needed, the namespace declaration will be created within the document. If possible, however, an existing namespace declaration within scope at the insertion point will be used. This may result in a change to the prefix, which is not incorrect, because the namespace itself is the important aspect here and not the prefix. I will illustrate how to do this in the examples in the Building an XSL Template example toward the end of this chapter. You can also directly instantiate elements using the new keyword. The firstname and surname elements, which will be the children of the bookinfo element, will be created using the newkeyword. The constructor for the DOMElement class takes the same parameters as the createElement() method. The first required parameter is the name of the elements, and the second is an optional value for the element: $firstname = new DOMElement(”firstname”, “Rob”); $surname = new DOMElement(”surname”, “Richards”);

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Cheap Web Hosting services

PHP, MySQL, Java, Unix Cheap Web Hosting

204 CHAPTER 6 DOCUMENT OBJECT MODEL (DOM)

Filed under: PHP and XML — webmaster @ 16:31

204 CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) DOMDocType object that can be passed as a parameter to create a document with a subset. This class allows static method calls, so in this case, you have no need to instantiate an object. For example: $doctype = DOMImplementation:: createDocumentType(”book”, “-//OASIS//DTD DocBook XML V4.1.2//EN”, “http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd”); $dom = DOMImplementation:: createDocument(NULL, “book”, $doctype); The first step is creating a DOMDoctType object, because it is needed when creating the document. You do this using the createDocumentType() method and passing the name for the document declaration, which, as you recall from Chapter 2, must match the name of the document element, the public identifier, and finally the system identifier. If the declaration is a system identifier, you pass NULL for the public identifier argument. The final step is to create the document using the createDocument() method. The first argument is the namespace for the document element. In this case, the document is not using namespaces, and you use NULL. The remaining parameters are the name of the document element, which will be created when the method returns, and the DOMDocType object, $doctype, that was created in the previous line. Upon executing this code, the DOMDocument object, $dom, will contain the document node with a DTD and the document element created. At this point, if the tree were output using a method such as saveXML(), you would notice that the encoding is missing. Using the DOMImplementationclass to create the document does not offer a way to set the version or encoding. The version at least defaults to 1.0. You can set the encoding using the encoding property of the document: $dom->encoding = “UTF-8″; This property does not affect how you create the document. Data that is not conformant to the internal UTF-8 encoding of the tree still needs to be converted to UTF-8. Upon output of the tree, however, the data is converted to the proper encoding set by this property. Element Nodes You can create, insert, and remove element nodes from a tree, but you cannot (unlike with most other nodes) edit their contents. Whether they are just text or combinations of other nodes, in order to edit them, you must access the child nodes or attributes. The next sections will take you through how to create, insert, and remove element nodes in a document. Creating Elements You have two ways to create element nodes. One is to use the factory methods from the DOMDocument object, and the other is direct instantiation. According to the specification, nodes must be associated with a document. The factory methods follow this rule. As you will see following the factory methods, the DOM extension allows direct instantiation of DOMElement objects, which results in element nodes with no tree association. This exists not only for convenience during development, but as discussed later in this chapter, it also allows for limited functionality of extending the DOM classes. As previously mentioned, the DOMDocument object is a focal object when using the DOM extension. You can create a new element associated to the current document using the factory methods createElement()and createElementNS(). The document that has been created to this

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Clan Web Hosting services

PHP, MySQL, Java, Unix Cheap Web Hosting

CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) 203

Filed under: PHP and XML — webmaster @ 06:35

CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) 203 attributes normally. It is the same as accessing attributes that do not live in any namespace. If the attributes were associated with a namespace, the results from the methods would be empty unless the appropriate namespace URI were passed as the first parameter. Declaring Namespaces Namespace declarations are handled as attributes within the DOM extension and as such are created using the namespace s attribute methods. The prefix xmlns is bound to the http:// www.w3.org/2000/xmlns/ namespace as defined in the XML 1.1 specification from the W3C (http://www.w3.org/TR/xml-names11/). For example: $doc = DOMDocument::loadXML(’‘); $root = $doc->documentElement; $root->setAttributeNS(’http://www.w3.org/2000/xmlns/’, ‘xmlns:exa’,'http://www.example.com/example’); $root->appendChild(new DOMElement(’exa:child’, ‘content’, ‘http://www.example.com/example’)); $doc->formatOutput = TRUE; print $doc->saveXML(); Using the setAttributeNS() method, a namespace that contains the prefix exa and is bound to http://www.example.com/example is declared. The namespace for the xmlns prefix is used as the namespace URI in this method, and the value of the attribute is the namespace that will be created. To declare a namespace, it is mandatory that the namespace URI parameter be the value http://www.w3.org/200/xmlns/; otherwise, the DOM extension will not know that a namespace is supposed to be created and a normal attribute will result. The following line illustrates how to append a new element bound to this newly created namespace, which results in the following document upon serialization: content Creating and Editing a Tree The DOM extension s biggest strength comes from its functionality for creating and editing trees. As you will see with the other XML technologies, none comes close to the capabilities the DOM extension offers in this respect. Unless you are a hard-core XML developer or integrator, you may end up using only a quarter of the offered functionality yet still encounter no shortcomings with the small subset of functionality used. Within the following sections, you will begin by creating the document in Listing 6-1 from scratch and then work on editing the result. Document Nodes Earlier in this chapter, you saw many different methods for creating a DOMDocument object. The document being created contains a document type declaration, so you will use the DOMImplementation class to create the DOMDocument object; this allows you to create a

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Clan Web Hosting services

PHP, MySQL, Java, Unix Cheap Web Hosting

202 CHAPTER 6 DOCUMENT OBJECT MODEL (DOM)

Filed under: PHP and XML — webmaster @ 20:33

202 CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) $attr = $attributes->getNamedItem(”lang”); print “Attribute Name: “.$attr->nodeName.”n”; print “Attribute Value: “.$attr->nodeValue.”n”; The document element contains only a single element, so the previous code returns the same results as the code iterating the attributes. This time, the lang attribute was accessed directly from the node map rather than iterating the entire map. Just like a DOMNodeList, the position could also have been used to access the attribute. Using a DOMNamedNodeMap, however, the items are unordered, so you have no guarantee that an item at a certain position is the item for which you are looking. For example: if ($attributes->length > 0) { $attr = $attributes->item(0); print “Attribute Name: “.$attr->nodeName.”n”; print “Attribute Value: “.$attr->nodeValue.”n”; } This code outputs the same results as before. The difference here is the test for the length of the DOMNamedNodeMap, which returns the number of items in the collection, and the use of the item() method to access the item at the zero-based index. Passing in the value of 0 for the argument returns the first item in the list, which is the lang attribute. Individual Attributes Attributes do not have to be accessed through a DOMNamedNodeMap. The DOMElement class offers attribute-specific methods that you can use to access specific attributes. The method used depends upon whether just the value of the attribute or the entire attribute node needs to be returned. It also depends upon whether namespaces are in use. You can access attributes using the getAttribute(), getAttributeNode(), getAttributeNS(), and getAttributeNodeNS() methods. For example: /* Access lang attribute value directly */ print “Attribute Value: “.$root->getAttribute(”lang”).”n”; /* Return the lang attribute node and access the returned attribute node */ $attr = $root->getAttributeNode(”lang”); print “Attribute Value: “.$attr->nodeValue.”n”; The previous two pieces of code print the same results but perform the operations differently. The first snippet returns the value of the named attribute, lang, and prints the value. The second block of code retrieves the attribute node named lang and prints the value from the returned node. Although the document in Listing 6-1 is not using namespaces, the namespace-aware methods can be used: print “Attribute Value: “.$root->getAttributeNS(NULL, “lang”).”n”; $attr = $root->getAttributeNodeNS(NULL, “lang”); print “Attribute Value: “.$attr->nodeValue.”n”; The first argument for these methods is the namespace URI for the attribute being accessed. Your attributes do not live in any namespaces, so by passing NULL, you access the

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Cheap Web Hosting services

PHP, MySQL, Java, Unix Cheap Web Hosting

CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) 201

Filed under: PHP and XML — webmaster @ 06:57

CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) 201 When working with namespaced documents, the getElementsByTagNameNS() method allows elements in specified namespaces to be returned. The example document in this chapter does not contain namespaces, so I cannot give a specific example at this time. The method differs from the non-namespaced method in that it takes two arguments. The first is the name- space URI, and the second is the local name of the element, which is the same as the tag name for the previous method. Just like the nameparameter, the namespace URI parameter also accepts the *wildcard. Using the wildcard results in retrieving all elements in any namespace, but they must be in a namespace with the name determined from the second parameter, which can also be a wildcard. For example: $result = $dom->getElementsByTagNameNS(”*”, “*”); The resulting DOMNodeList, $result, will contain every element in the document that is within any namespace. Accessing Attributes Attributes inherit the same methods and properties from the DOMNode class as other node types, but they are not accessed in the same manner as other nodes in a document. As you have seen so far, nodes are traversed through children of nodes. Attributes are different because they are not children of elements, which is the only node type from which attributes may reside; rather, attributes, conceptually, are properties of elements. You access them through their own set of properties and methods. Collections of Attributes Just like you can check and access children, you can check attributes with the hasAttributes() method and access them with the attributes property. Both of these are defined on the DOMNode class and are safe to use with all node types, although an object of DOMElement will be the only class type that can return useful data: if ($root->hasAttributes()) { $attributes = $root->attributes; foreach($attributes as $attr) { print “Attribute Name: “.$attr->nodeName.”n”; print “Attribute Value: “.$attr->nodeValue.”n”; } } If attributes exist on the $root object, tested using the hasAttributes() method, a DOMNamedNodeMap object, $attributes, is returned from the attributes property. This object is iterated in the same way the DOMNodeList is iterated. The resulting output for this code is as follows: Attribute Name: lang Attribute Value: en One of the differences with the node map is that attributes can be accessed directly by name rather than just a position. For example:

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Cheap Web Hosting services

PHP, MySQL, Java, Unix Cheap Web Hosting

200 CHAPTER 6 DOCUMENT OBJECT MODEL (DOM)

Filed under: PHP and XML — webmaster @ 20:08

200 CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) nodes and element nodes; thus, these methods are available only when the current node is based on a DOMDocument or DOMElementclass. For example, from the document node, $dom, you can retrieve all title elements within the document using the getElementsByTagName() method: $elements = $dom->getElementsByTagName(”title”); $length = $elements->length; for ($x=0;$x < $length;$x++) { print "Element Value: ".$elements->item($x)->nodeValue.”n”; } This code retrieves a DOMNodeList object, $elements, containing all title elements within the scope of the document node, $dom. Being the document node, this returns all elements named title within the entire document. The collection is iterated using a for loop based on length, indicating the number of nodes within the collection. length is the total number of elements, and the collection uses a zero-based index, so no items are at an index equal to or greater than the length. Using dereferencing (available in PHP 5), the element at the current index, $x, is retrieved, and the nodeValue for the node is printed. The output from this operation is as follows: Element Value: DOM in PHP 5 Element Value: The DOM Tree Element Value: Navigating The Tree You can pass the special value * for the tag name argument. This is a wildcard used to match any element name. For example: $preface = $root->getElementsByTagName(”preface”); $elements = $preface->item(0)->getElementsByTagName(”*”); $length = $elements->length; for ($x=0;$x < $length;$x++) { print "Element Name: ".$elements->item($x)->nodeName.”n”; print “Element Value: “.$elements->item($x)->nodeValue.”n”; } From the document element, $root, all preface elements within its scope are retrieved as a DOMNodeListobject, $preface. No length test is performed, because you already know that an element exists in the document (although it is a good habit to test the return values prior to using them). Again, dereferencing is used; the first element in the DOMNodeList is retrieved, and immediately in the same line of code, getElementsByTageName(”*”) is called on the node. All elements within the scope of the preface element are returned and set to the $elements variable. You can access this collection the same way as before: by using a for loop. This time the node name is also printed with its value, because you have no way to know exactly what elements are returned when using the wildcard. The resulting output is as follows: Element Name: title Element Value: The DOM Tree Element Name: para Element Value: An example DOM Tree using DocBook.

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost PHP MySQL Web Hosting services

PHP, MySQL, Java, Unix Cheap Web Hosting

CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) 199

Filed under: PHP and XML — webmaster @ 08:33

CHAPTER 6 DOCUMENT OBJECT MODEL (DOM) 199 do { $node = $first; while($node) { if (! $node->parentNode->isSameNode($root)) { print “ERROR: Parent Node Test FAILED”; break 2; } $node = $node->nextSibling; } print “All parent node tests PASSED”; } while(0); Using the code from the nextSibling example, the parentNode for each of the nodes, including the text nodes, is returned and tested against the document element, $root, using the isSameNode() method. This example uses object dereferencing features from PHP 5 and is equivalent to writing the following: $parent = $node->parentNode; if (! $parent->isSameNode($root)) { … The isSameNode() method tests the current node against the node passed as an argument to determine whether they are the same node. By same node, I mean the nodes must be the same node within the document. This is not the same as saying the nodes are equivalent; equivalent nodes must just have the same names and content but do not have to be the same node with the same position in the document. As you can see from the resulting All parent node tests PASSED message, the parent node for these is the document element, $root. Nodes have direct access to their associated document through the ownerDocument property. Although the body is accessible using the documentElement property, the document node is still an important node even when not needing or using a DTD. Later in this chapter, in the Document Nodes section, you will learn how to use the document node object for factory methods. This node provides much of the functionality used when creating and editing documents and is accessed frequently in applications. For example: $node = $root->ownerDocument; print $node->nodeName.”n”; The code prints the value #document, because the document node is returned from the property. To verify this, you can execute the following code using the isSameNode() method: if ($dom->isSameNode($node)) print “TRUE”; Accessing Specific Elements You can also access specific elements by tag names. When you need to access specific elements within the scope of the current node, you can use the methods getElementsByTagName() and getElementsByTagNameNS(). Element nodes can be contained only within document

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Clan Web Hosting services

« Previous PageNext Page »

Powered by Cheap Web Hosting