advanced xml with php 5 - cdata zone

116
Advanced XML Advanced XML with PHP 5 with PHP 5 March 14, 2007 March 14, 2007 Robert Richards Robert Richards [email protected] [email protected] http://www.cdatazone.org/talks/quebec_2007/workshop.zip http://www.cdatazone.org/talks/quebec_2007/workshop.zip

Upload: others

Post on 12-Sep-2021

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Advanced XML with PHP 5 - CDATA Zone

Advanced XML Advanced XML with PHP 5with PHP 5

March 14, 2007March 14, 2007Robert RichardsRobert Richards

[email protected]@ctindustries.nethttp://www.cdatazone.org/talks/quebec_2007/workshop.ziphttp://www.cdatazone.org/talks/quebec_2007/workshop.zip

Page 2: Advanced XML with PHP 5 - CDATA Zone

AgendaAgenda� Introduction to Terms and ConceptsIntroduction to Terms and Concepts� LibxmlLibxml� SimpleXMLSimpleXML� SDOSDO� DOMDOM� XMLReaderXMLReader� XMLWriterXMLWriter� XSLXSL

Page 3: Advanced XML with PHP 5 - CDATA Zone

XML NamespacesXML Namespaces

� An XML Namespace is a collection of names An XML Namespace is a collection of names identified by a URI.identified by a URI.

� They are applicable to elements and attributes.They are applicable to elements and attributes.� Namespaces may or may not be associated with a Namespaces may or may not be associated with a

prefix.prefix.� xmlns:rob="urn:rob"xmlns:rob="urn:rob"� xmlns=xmlns=http://www.example.com/robhttp://www.example.com/rob

� Attributes never reside within a default namespace.Attributes never reside within a default namespace.� It is illegal to have two attributes with the same It is illegal to have two attributes with the same

localname and same namespace on the same element.localname and same namespace on the same element.

Page 4: Advanced XML with PHP 5 - CDATA Zone

XML Namespace ExampleXML Namespace Example

<order num="1001"> <shipping> <name type="care_of">John Smith</name> <address>123 Here</address> </shipping> <billing> <name type="legal">Jane Doe</name> <address>456 Somewhere else</address> </billing></order>

Page 5: Advanced XML with PHP 5 - CDATA Zone

XML Namespace ExampleXML Namespace Example<order num="1001" xmlns="urn:order" xmlns:ship="urn:shipping" xmlns:bill="urn:billing"> <ship:shipping> <ship:name type="care_of">John Smith</ship:name> <ship:address>123 Here</ship:address> </ship:shipping> <bill:billing> <bill:name type="legal">Jane Doe</bill:name> <bill:address>456 Somewhere else</bill:address> </bill:billing></order>

Page 6: Advanced XML with PHP 5 - CDATA Zone

Illegal Namespace UsageIllegal Namespace Usage<order num="1001" xmlns="urn:order"<order num="1001" xmlns="urn:order"

xmlns:order="urn:order"xmlns:order="urn:order" xmlns:ship="urn:order"xmlns:ship="urn:order" >>

<shipping ship:type="fed_ex" type="fed_ex"><shipping ship:type="fed_ex" type="fed_ex">

<name <name ship:type="care_of"ship:type="care_of"

order:type="legal"order:type="legal" >John Smith</ship:name>>John Smith</ship:name>

</ship:shipping></ship:shipping>

</order></order>

Both "type" attributes are bound to same namespace which is not valid!

Page 7: Advanced XML with PHP 5 - CDATA Zone

Illegal Namespace UsageIllegal Namespace Usage<order num="1001" xmlns="urn:order"<order num="1001" xmlns="urn:order"

xmlns:order="urn:order"xmlns:order="urn:order"

xmlns:ship="urn:order">xmlns:ship="urn:order">

<shipping <shipping ship:type="fed_ex" type="fed_ex"ship:type="fed_ex" type="fed_ex" >>

<name ship:type="care_of" <name ship:type="care_of"

order:type="legal">John Smith</ship:name>order:type="legal">John Smith</ship:name>

</ship:shipping></ship:shipping>

</order></order>

<!-- attributes on shipping element are valid ! --><!-- attributes on shipping element are valid ! -->

Page 8: Advanced XML with PHP 5 - CDATA Zone

Reserved Namespaces and Reserved Namespaces and PrefixesPrefixes

� The prefix The prefix xmlxml is bound to is bound to http://www.w3.org/XML/1998/namespacehttp://www.w3.org/XML/1998/namespace..

� The prefix The prefix xmlnsxmlns is bound to is bound to http://www.w3.org/2000/xmlns/http://www.w3.org/2000/xmlns/..

� Prefixes should also not begin with the Prefixes should also not begin with the characters characters xmlxml..

Page 9: Advanced XML with PHP 5 - CDATA Zone

Schemas and ValidationSchemas and Validation

� Validation insures an XML document Validation insures an XML document conforms to a set of defined rules.conforms to a set of defined rules.

� Multiple mechanisms exist to write document Multiple mechanisms exist to write document rule sets:rule sets:� Document Type Definition (DTD)Document Type Definition (DTD)� XML SchemaXML Schema� RelaxNGRelaxNG

Page 10: Advanced XML with PHP 5 - CDATA Zone

Document Type Definition Document Type Definition (DTD)(DTD)validation/courses-dtd.xmlvalidation/courses-dtd.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE courses [ <!ELEMENT courses (course+)> <!ELEMENT course (title, description, credits, lastmodified)> <!ATTLIST course cid ID #REQUIRED> <!ELEMENT title (#PCDATA)> <!ELEMENT description (#PCDATA)> <!ELEMENT credits (#PCDATA)> <!ELEMENT lastmodified (#PCDATA)>]><courses> <course cid="c1"> <title>Basic Languages</title> <description>Introduction to Languages</description> <credits>1.5</credits> <lastmodified>2004-09-01T11:13:01</lastmodified> </course></courses>

Page 11: Advanced XML with PHP 5 - CDATA Zone

DTD and IDsDTD and IDsvalidation/course-id.xmlvalidation/course-id.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE courses [ <!ATTLIST course cid ID #REQUIRED>]><courses> <course cid="c1"> <title xml:id="t1">Basic Languages</title> <description>Introduction to Languages</description> </course> <course cid="c2"> <title xml:id="t3">French I</title> <description>Introduction to French</description> </course></courses>

Page 12: Advanced XML with PHP 5 - CDATA Zone

XML SchemaXML Schemavalidation/course.xsdvalidation/course.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="courses"> <xsd:complexType> <xsd:sequence> <xsd:element name="course" minOccurs="1" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="title" type="xsd:string"/> <xsd:element name="description" type="xsd:string"/> <xsd:element name="credits" type="xsd:decimal"/> <xsd:element name="lastmodified" type="xsd:dateTime"/> </xsd:sequence> <xsd:attribute name="cid" type="xsd:ID"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element></xsd:schema>

Page 13: Advanced XML with PHP 5 - CDATA Zone

RelaxNGRelaxNGvalidation/course.rngvalidation/course.rng

<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">

<start> <element name="courses"> <oneOrMore> <element name="course"> <attribute name="cid"><data type="ID"/></attribute> <element name="title"><text/></element> <element name="description"><text/></element> <element name="credits"><data type="decimal"/></element> <element name="lastmodified"><data type="dateTime"/></element> </element> </oneOrMore> </element> </start>

</grammar>

Page 14: Advanced XML with PHP 5 - CDATA Zone

XPathXPath

� Language to locate and retrieve information Language to locate and retrieve information from an XML documentfrom an XML document

� A foundation for XSLTA foundation for XSLT� An XML document is a tree containing nodesAn XML document is a tree containing nodes� The XML document is the root nodeThe XML document is the root node� Locations are addressable similar to the syntax Locations are addressable similar to the syntax

for a filesystemfor a filesystem

Page 15: Advanced XML with PHP 5 - CDATA Zone

XPath Reference DocumentXPath Reference Documentxpath/courses.xmlxpath/courses.xml

<courses xmlns:t="http://www.example.com/title">

<course xml:id="c2"> <t:title>French I</t:title> <description>Introduction to French</description> </course>

<course xml:id="c3"> <t:title>French II</t:title> <description>Intermediate French</description> <pre-requisite cref="c2" /> <defns xmlns="urn::default">content</defns> </course>

</courses>

Page 16: Advanced XML with PHP 5 - CDATA Zone

XPath Location ExampleXPath Location Examplexpath/location.phpxpath/location.php

/courses/course/description/courses/*/description//description//description[ancestor::course]

Expression:

Resulting Nodset:

<description>Introduction to French</description><description>Intermediate French</description>

Page 17: Advanced XML with PHP 5 - CDATA Zone

XPath Function ExampleXPath Function Examplexpath/function.phpxpath/function.php

string(/courses/course/pre-requisite[@cref="c2"]/..)string(/courses/course/pre-requisite[@cref="c2"]/..)

French IIFrench II Intermediate FrenchIntermediate French contentcontent

Reference:Reference:<courses xmlns:t="http://www.example.com/title"><courses xmlns:t="http://www.example.com/title"> <course xml:id="c3"><course xml:id="c3"> <!-- additional elements containing the textual content ommitted for brevity --><!-- additional elements containing the textual content ommitted for brevity --> <pre-requisite cref="c2" /><pre-requisite cref="c2" /> </course></course></courses></courses>

Page 18: Advanced XML with PHP 5 - CDATA Zone

XPath and NamespacesXPath and Namespacesxpath/namespaces.phpxpath/namespaces.php

//titleEmpty NodeSet

//defnsEmpty NodeSet

<defns xmlns="urn:default">content</defns>

//t:title<t:title>French I</t:title><t:title>French II</t:title>

//*[local-name()="defns"]

<courses xmlns:t="http://www.example.com/title"> <course xml:id="c2"> <t:title>French I</t:title> </course>

<course xml:id="c3"> <t:title>French II</t:title> <defns xmlns="urn::default">content</defns> </course></courses>

Reference:

Page 19: Advanced XML with PHP 5 - CDATA Zone

PHP and XMLPHP and XML

� PHP 5 introduced numerous interfaces for PHP 5 introduced numerous interfaces for working with XMLworking with XML

� The libxml2 library (http://www.xmlsoft.org/) The libxml2 library (http://www.xmlsoft.org/) was chosen to provide XML supportwas chosen to provide XML support

� The sister library libxslt provides XSLT supportThe sister library libxslt provides XSLT support� I/O is handled via PHP streamsI/O is handled via PHP streams� ext/domxml was removed in favor of ext/domext/domxml was removed in favor of ext/dom

Page 20: Advanced XML with PHP 5 - CDATA Zone

XML Entensions for PHP 5XML Entensions for PHP 5

� ext/libxmlext/libxml� ext/xml (SAX push parser)ext/xml (SAX push parser)� ext/domext/dom� ext/simplexmlext/simplexml� ext/xmlreader (pull parser)ext/xmlreader (pull parser)� pecl/sdo (SCA_SDO)pecl/sdo (SCA_SDO)� ext/xmlwriterext/xmlwriter� ext/xslext/xsl� ext/wddxext/wddx� ext/soapext/soap

Page 21: Advanced XML with PHP 5 - CDATA Zone

LibxmlLibxml

� Contains common functionality shared across Contains common functionality shared across extensions.extensions.

� Defines constants to modify parse time Defines constants to modify parse time behavior.behavior.

� Provides access to streams context.Provides access to streams context.� Allows modification of error handling Allows modification of error handling

behavior for XML based extensions.behavior for XML based extensions.

Page 22: Advanced XML with PHP 5 - CDATA Zone

Libxml: Parser OptionsLibxml: Parser Options

Disable network access when loadingLIBXML_NONET

Merge CDATA nodes in Text nodesLIBXML_NOCDATA

Perform XIncludes during parsingLIBXML_XINCLUDE

Remove insignificant whitespace on parsingLIBXML_NOBLANKS

Suppress parser warnings from libxml2LIBXML_NOWARNING

Suppress parsing errors from libxml2LIBXML_NOERROR

Loads subsets and perform validationLIBXML_DTDVALID

Create defaulted attributes defined in DTDLIBXML_DTDATTR

Load subsets but do not perform validationLIBXML_DTDLOAD

Substitute entities with replacement contentLIBXML_NOENT

Page 23: Advanced XML with PHP 5 - CDATA Zone

Libxml: Error HandlingLibxml: Error Handling

bool libxml_use_internal_errors ([bool use_errors])bool libxml_use_internal_errors ([bool use_errors])

void libxml_clear_errors ( void )void libxml_clear_errors ( void )

LibXMLError libxml_get_last_error ( void )LibXMLError libxml_get_last_error ( void )

array libxml_get_errors ( void )array libxml_get_errors ( void )

Page 24: Advanced XML with PHP 5 - CDATA Zone

Libxml: LibXMLErrorLibxml: LibXMLError

Class: LibXMLErrorProperties (Read-Only):

(int) level(int) code(int) column(string) message(string) file(int) line

LibXMLError::code Values:LIBXML_ERR_NONELIBXML_ERR_WARNINGLIBXML_ERR_ERRORLIBXML_ERR_FATAL

Page 25: Advanced XML with PHP 5 - CDATA Zone

LibXMLError ExampleLibXMLError Examplelibxml/error.phplibxml/error.php

<?php/* Regular Error Handling */$dom = new DOMDocument();$dom->loadXML('<root>');

/* New Error Handling */libxml_use_internal_errors(TRUE);

if (! $dom->loadXML('root')) { $arrError = libxml_get_errors(); foreach ($arrError AS $xmlError) { var_dump($xmlError); }} else { print "Document Loaded";}?>

Page 26: Advanced XML with PHP 5 - CDATA Zone

LibXMLError ResultLibXMLError Result

PHP Warning: DOMDocument::loadXML(): Premature end of data in tag root line 1 PHP Warning: DOMDocument::loadXML(): Premature end of data in tag root line 1 in Entity, line: 1 in /home/rrichards/workshop/libxml/error.php on line 4in Entity, line: 1 in /home/rrichards/workshop/libxml/error.php on line 4

Warning: DOMDocument::loadXML(): Premature end of data in tag root line 1 in Warning: DOMDocument::loadXML(): Premature end of data in tag root line 1 in Entity, line: 1 in /home/rrichards/workshop/libxml/error.php on line 4Entity, line: 1 in /home/rrichards/workshop/libxml/error.php on line 4

New Error Handling:New Error Handling:object(LibXMLError)#2 (6) {object(LibXMLError)#2 (6) { ["level"]=> int(3)["level"]=> int(3) ["code"]=> int(4)["code"]=> int(4) ["column"]=> int(1)["column"]=> int(1) ["message"]=> string(34) "Start tag expected, '<' not found"["message"]=> string(34) "Start tag expected, '<' not found" ["file"]=> string(0) ""["file"]=> string(0) "" ["line"]=> int(1)["line"]=> int(1)}}

Page 27: Advanced XML with PHP 5 - CDATA Zone

Libxml: Stream ContextLibxml: Stream Context

$opts = array($opts = array(

'http' => array('http' => array('user_agent' => 'PHP libxml2 agent','user_agent' => 'PHP libxml2 agent',

'proxy' => 'tcp://localhost:8082','proxy' => 'tcp://localhost:8082',

'request_fulluri' => TRUE'request_fulluri' => TRUE

))););

$context = stream_context_create($opts);$context = stream_context_create($opts);libxml_set_streams_context($context);libxml_set_streams_context($context);

$doc = DOMDocument::load('http://www.example.org/file.xml');$doc = DOMDocument::load('http://www.example.org/file.xml');

Page 28: Advanced XML with PHP 5 - CDATA Zone

Preparing for Unicode in PHP 6Preparing for Unicode in PHP 6

� XML extensions are unicode ready for PHP 6XML extensions are unicode ready for PHP 6� Both the UTF-8 binary strings (existing behavior) Both the UTF-8 binary strings (existing behavior)

ANDAND unicode strings. unicode strings.� With Unicode enabled, unicode strings are returned With Unicode enabled, unicode strings are returned

instead of the current UTF-8 binary strings.instead of the current UTF-8 binary strings.

� Binary strings are required for Loading and Binary strings are required for Loading and Saving Saving StringString based XML documents based XML documents� Insures original encoding is not lostInsures original encoding is not lost� Does not affect usage with unicode disabledDoes not affect usage with unicode disabled

Page 29: Advanced XML with PHP 5 - CDATA Zone

Forward CompatibilityForward Compatibility

$xml = $xml = (binary)(binary) "<root>My Document</root>";"<root>My Document</root>";$sxe = simplexml_load_string($xml);$sxe = simplexml_load_string($xml);

$xml = $xml = bb'<root>MyDocument</root>';'<root>MyDocument</root>';$dom = new DOMDocument();$dom = new DOMDocument();$dom->loadXML($xml);$dom->loadXML($xml);

$sxe = simplexml_load_string($dom->saveXML());$sxe = simplexml_load_string($dom->saveXML());

Page 30: Advanced XML with PHP 5 - CDATA Zone

SimpleXMLSimpleXML

� Provides simple access to XML documentsProvides simple access to XML documents� Operates only on elements and attributesOperates only on elements and attributes� Contains XPath supportContains XPath support� Allows for modifications to the XMLAllows for modifications to the XML� Zero copy interoperability with DOMZero copy interoperability with DOM� Examples for PHP 5.1.6+Examples for PHP 5.1.6+� New in PHP 5.1.3New in PHP 5.1.3

� Elements and attributes can be added using addChild() and Elements and attributes can be added using addChild() and addAttribute() methods.addAttribute() methods.

� Node names can be retrieved by calling getName().Node names can be retrieved by calling getName().

Page 31: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Consuming Yahoo WebSearch SimpleXML: Consuming Yahoo WebSearch simplexml/yahoo_websearch_results.xmlsimplexml/yahoo_websearch_results.xml

<ResultSet <ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" totalResultsReturnedtotalResultsReturned="3" firstResultPosition="1">="3" firstResultPosition="1">

<<ResultResult>> <<TitleTitle>Zend Technologies - PHP 5 . . .</Title>>Zend Technologies - PHP 5 . . .</Title> <Summary>titletext = $dom-&amp;gt;createText. . .</Summary><Summary>titletext = $dom-&amp;gt;createText. . .</Summary> <<UrlUrl >http://www.zend.com/php5/articles/php5-x. . .</Url>>http://www.zend.com/php5/articles/php5-x. . .</Url> <ClickUrl>http://uk.wrs.yahoo.com/_ylt=...</ClickUrl><ClickUrl>http://uk.wrs.yahoo.com/_ylt=...</ClickUrl> <DisplayUrl>www.zend.com/php5/articles/php. . .</DisplayUrl><DisplayUrl>www.zend.com/php5/articles/php. . .</DisplayUrl> <<ModificationDateModificationDate>1171872000</ModificationDate>>1171872000</ModificationDate> <MimeType>text/html</MimeType><MimeType>text/html</MimeType> <!-- Abbreviated Content --><!-- Abbreviated Content --> </Result></Result>

<!-- Abbreviated Response --><!-- Abbreviated Response --></ResultSet></ResultSet>

Page 32: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Consuming Yahoo WebSearch SimpleXML: Consuming Yahoo WebSearch simplexml/yahoo_search.phpsimplexml/yahoo_search.php

/* URL to Web Search service *//* URL to Web Search service */$url = 'http://api.search.yahoo.com/WebSearchService/V1/webSearch';$url = 'http://api.search.yahoo.com/WebSearchService/V1/webSearch';/* The query is separate here as the terms must be encoded. *//* The query is separate here as the terms must be encoded. */$url .= '?query='.rawurlencode('php5 xml');$url .= '?query='.rawurlencode('php5 xml');/* Complete the URL adding App ID, limit to 3 results and only English results *//* Complete the URL adding App ID, limit to 3 results and only English results */$url .= "&appid=zzz&results=3&language=en";$url .= "&appid=zzz&results=3&language=en";

$sxe = simplexml_load_file($url);$sxe = simplexml_load_file($url);

/* Check for number of results returned *//* Check for number of results returned */if ((int)$sxe['totalResultsReturned'] > 0) {if ((int)$sxe['totalResultsReturned'] > 0) {

/* Loop through results and print title, url and modification date *//* Loop through results and print title, url and modification date */ foreach ($sxe->Result AS $result) {foreach ($sxe->Result AS $result) { print 'Title: '.$result->Title."\n";print 'Title: '.$result->Title."\n"; print 'Url: '.$result->Url."\n";print 'Url: '.$result->Url."\n"; print 'Mod Date: '.date ('M d Y', (int)$result->ModificationDate)."\n\n";print 'Mod Date: '.date ('M d Y', (int)$result->ModificationDate)."\n\n"; }}}}

Page 33: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Consuming Yahoo WebSearch SimpleXML: Consuming Yahoo WebSearch RESULTSRESULTS

Title: Zend Technologies - PHP 5 In Depth - XML in PHP 5 - What's New?Title: Zend Technologies - PHP 5 In Depth - XML in PHP 5 - What's New?Url: http://www.zend.com/php5/articles/php5-xmlphp.phpUrl: http://www.zend.com/php5/articles/php5-xmlphp.phpMod Date: Feb 19 2007Mod Date: Feb 19 2007

Title: Zend Developer Zone | XML in PHP 5 - What's New?Title: Zend Developer Zone | XML in PHP 5 - What's New?Url: http://devzone.zend.com/node/view/id/1713Url: http://devzone.zend.com/node/view/id/1713Mod Date: Feb 26 2007Mod Date: Feb 26 2007

Title: FreshPorts -- textproc/php5-xmlTitle: FreshPorts -- textproc/php5-xmlUrl: http://www.freshports.org/textproc/php5-xmlUrl: http://www.freshports.org/textproc/php5-xmlMod Date: Feb 15 2007Mod Date: Feb 15 2007

Page 34: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: NamespacesSimpleXML: Namespacessimplexml/sxe_ns_books.phpsimplexml/sxe_ns_books.php

<books <books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book">> <bk:book qty="25"><bk:book qty="25"> <bk:name>Grapes of Wrath</bk:name><bk:name>Grapes of Wrath</bk:name> <bk:price>12.99</bk:price><bk:price>12.99</bk:price> </bk:book></bk:book>

<book qty="33" xmlns="http://www.example.com/ExteralClassics"><book qty="33" xmlns="http://www.example.com/ExteralClassics"> <name>To Kill a Mockingbird</name><name>To Kill a Mockingbird</name> <price>10.99</price><price>10.99</price> </book></book></books></books>

$books = simplexml_load_file('sxe_ns_books.xml');$books = simplexml_load_file('sxe_ns_books.xml');

foreach ($books->book AS $book) {foreach ($books->book AS $book) { if ($book->if ($book->namename)) print $book->name;print $book->name;}}

Page 35: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Namespaces SimpleXML: Namespaces ResultsResults

To Kill a MockingbirdTo Kill a Mockingbird

Question:Question:

What happened to the other book title?What happened to the other book title?

Page 36: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: NamespacesSimpleXML: Namespacessimplexml/sxe_ns_books_prefix.phpsimplexml/sxe_ns_books_prefix.php

<books <books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book">> <bk:book qty="25"><bk:book qty="25"> <bk:name>Grapes of Wrath</bk:name><bk:name>Grapes of Wrath</bk:name> <bk:price>12.99</bk:price><bk:price>12.99</bk:price> </bk:book></bk:book>

<book qty="33" xmlns="http://www.example.com/ExteralClassics"><book qty="33" xmlns="http://www.example.com/ExteralClassics"> <name>To Kill a Mockingbird</name><name>To Kill a Mockingbird</name> <price>10.99</price><price>10.99</price> </book></book></books></books>

$books = simplexml_load_file('sxe_ns_books.xml');$books = simplexml_load_file('sxe_ns_books.xml');

$children = $books->children("http://www.example.com/book");$children = $books->children("http://www.example.com/book");foreach ($children->book AS $book) {foreach ($children->book AS $book) { print $book->name."\n";print $book->name."\n";}}

Page 37: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Namespaces SimpleXML: Namespaces ResultsResults

Grapes of WrathGrapes of Wrath

Only book elements within the specified Only book elements within the specified namespace are used in the resultsnamespace are used in the results

Page 38: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: XpathSimpleXML: Xpathsimplexml/sxe_xpath_ns.phpsimplexml/sxe_xpath_ns.php

<books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"><books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"> <bk:book qty="25"><bk:book qty="25"> <bk:name>Grapes of Wrath</bk:name><bk:name>Grapes of Wrath</bk:name> <bk:price>12.99</bk:price><bk:price>12.99</bk:price> </bk:book></bk:book> <book qty="33" xmlns="http://www.example.com/ExteralClassics" xmlns:pc="urn::pricing"><book qty="33" xmlns="http://www.example.com/ExteralClassics" xmlns:pc="urn::pricing"> <name>To Kill a Mockingbird</name><name>To Kill a Mockingbird</name> <pc:price>10.99</pc:price><pc:price>10.99</pc:price> </book></book></books></books>

$sxe = simplexml_load_file('$sxe = simplexml_load_file('sxe_ns_books.xmlsxe_ns_books.xml');');

$nodelist = $sxe->xpath("//name");$nodelist = $sxe->xpath("//name");print "Book Title: ".$nodelist[0]."\n";print "Book Title: ".$nodelist[0]."\n";

$nodelist = $sxe->xpath("//bk:name");$nodelist = $sxe->xpath("//bk:name");print "Book Title: ".$nodelist[0]."\n";print "Book Title: ".$nodelist[0]."\n";

Page 39: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: XPath ResultsSimpleXML: XPath Results

Book Title: Book Title:

Book Title: Book Title: Grapes of WrathGrapes of Wrath

Why doesn't the title "Why doesn't the title "To Kill a Mockingbird" To Kill a Mockingbird" get printed?get printed?

Page 40: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: XpathSimpleXML: Xpathsimplexml/sxe_xpath_ns_def.phpsimplexml/sxe_xpath_ns_def.php

<books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"><books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"> <bk:book qty="25"><bk:book qty="25"> <bk:name>Grapes of Wrath</bk:name><bk:name>Grapes of Wrath</bk:name> <bk:price>12.99</bk:price><bk:price>12.99</bk:price> </bk:book></bk:book> <book qty="33" xmlns="http://www.example.com/ExteralClassics" xmlns:pc="urn::pricing"><book qty="33" xmlns="http://www.example.com/ExteralClassics" xmlns:pc="urn::pricing"> <name>To Kill a Mockingbird</name><name>To Kill a Mockingbird</name> <pc:price>10.99</pc:price><pc:price>10.99</pc:price> </book></book></books></books>

$sxe = simplexml_load_file('$sxe = simplexml_load_file('sxe_ns_books.xmlsxe_ns_books.xml');');

$sxe->registerXPathNamespace("ec", "$sxe->registerXPathNamespace("ec", "http://www.example.com/ExteralClassicshttp://www.example.com/ExteralClassics");");

$nodelist = $sxe->xpath("//ec:name");$nodelist = $sxe->xpath("//ec:name");print "Book Title: ".$nodelist[0]."\n";print "Book Title: ".$nodelist[0]."\n";

Book Title: To Kill a MockingbirdBook Title: To Kill a Mockingbird

Page 41: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: XPath ContextSimpleXML: XPath Contextsimplexml/sxe_xpath_context.phpsimplexml/sxe_xpath_context.php

$xml = <<< EOXML$xml = <<< EOXML<books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"><books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"> <book qty="33" xmlns="http://www.example.com/ExteralClassics" xmlns:pc="urn::pricing"><book qty="33" xmlns="http://www.example.com/ExteralClassics" xmlns:pc="urn::pricing"> <name>To Kill a Mockingbird</name><name>To Kill a Mockingbird</name> <pc:price>10.99</pc:price><pc:price>10.99</pc:price> </book></book></books></books>EOXML;EOXML;

libxml_use_internal_errors(TRUE);libxml_use_internal_errors(TRUE);

$books = simplexml_load_string($xml);$books = simplexml_load_string($xml);$books->registerXPathNamespace("pc", "urn::pricing");$books->registerXPathNamespace("pc", "urn::pricing");

$nodelist = $books->xpath("//ec:name");$nodelist = $books->xpath("//ec:name");$pricing = $books->book->xpath("./pc:price");$pricing = $books->book->xpath("./pc:price");print "Book Price: $".$pricing[0]."\n";print "Book Price: $".$pricing[0]."\n";

RESULTSRESULTSBook Price: $Book Price: $

Page 42: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: XPath ContextSimpleXML: XPath Contextsimplexml/sxe_xpath_ns_context.phpsimplexml/sxe_xpath_ns_context.php

$xml = <<< EOXML$xml = <<< EOXML<books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"><books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"> <book qty="33" xmlns="http://www.example.com/ExteralClassics" xmlns:pc="urn::pricing"><book qty="33" xmlns="http://www.example.com/ExteralClassics" xmlns:pc="urn::pricing"> <name>To Kill a Mockingbird</name><name>To Kill a Mockingbird</name> <pc:price>10.99</pc:price><pc:price>10.99</pc:price> </book></book></books></books>EOXML;EOXML;

$books = simplexml_load_string($xml);$books = simplexml_load_string($xml);

$book = $books->book[0]; $book = $books->book[0]; /* GOTCHA TO BE AWARE OF*//* GOTCHA TO BE AWARE OF*/$book->registerXPathNamespace("pc", "urn::pricing");$book->registerXPathNamespace("pc", "urn::pricing");

$pricing = $book->xpath("./pc:price");$pricing = $book->xpath("./pc:price");

print "Book Price: $".$pricing[0]."\n";print "Book Price: $".$pricing[0]."\n";

RESULTSRESULTSBook Price: $10.99Book Price: $10.99

Page 43: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Write some dataSimpleXML: Write some data

$data = "<root><top><![CDATA[ Some text]]></top></root>";$data = "<root><top><![CDATA[ Some text]]></top></root>";

/* We can even pass libxml parser options *//* We can even pass libxml parser options */$sxe = new SimpleXMLElement($data, LIBXML_NOCDATA);$sxe = new SimpleXMLElement($data, LIBXML_NOCDATA);

$sxe->child = 'new child';$sxe->child = 'new child';$sxe->child2 = 'second child';$sxe->child2 = 'second child';

print $sxe->asXML();print $sxe->asXML();

<?xml version="1.0"?><?xml version="1.0"?><root><top> Some text</top><child>new <root><top> Some text</top><child>new child</child><child2>second child</child2></root>child</child><child2>second child</child2></root>

Page 44: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Reading Data can SimpleXML: Reading Data can Create Data?Create Data?

ISSUE IS RESOLVED IN PHP 5.2.1+ISSUE IS RESOLVED IN PHP 5.2.1+

$sxe = new SimpleXMLElement("<root />");$sxe = new SimpleXMLElement("<root />");

foreach ($sxe->childr AS $child) {foreach ($sxe->childr AS $child) { var_dump($child);var_dump($child);}}print $sxe->asXML();print $sxe->asXML();

????? RESULTS ?????????? RESULTS ?????<?xml version="1.0"?><?xml version="1.0"?><root><childr/></root><root><childr/></root>

Page 45: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Advanced EditingSimpleXML: Advanced Editingsimplexml/editing.phpsimplexml/editing.php

$data = array(array('title'=>'Result 1', 'descript'=>'Res1 description'), $data = array(array('title'=>'Result 1', 'descript'=>'Res1 description'), array('title'=>'Result 2', 'descript'=>'description of Res2'), array('title'=>'Result 2', 'descript'=>'description of Res2'), array('title'=>'Result 3', 'descript'=>'This is result 3'));array('title'=>'Result 3', 'descript'=>'This is result 3'));

class webservice extends simpleXMLElement {class webservice extends simpleXMLElement { public function appendElement($name, $value=NULL) {public function appendElement($name, $value=NULL) { $count = (isset($this->{$name}))?count($this->{$name}):0;$count = (isset($this->{$name}))?count($this->{$name}):0; if ($count) {if ($count) { $this->{$name}[$count] = $value;$this->{$name}[$count] = $value; } else { } else { /* An issue requires first child be created without offset *//* An issue requires first child be created without offset */ $this->{$name} = $value;$this->{$name} = $value; }} return $this->{$name}[$count];return $this->{$name}[$count];} }} }

$rest = simplexml_load_string('<results num="0" />', $rest = simplexml_load_string('<results num="0" />', 'webservice''webservice'););$rest['num'] = count($data);$rest['num'] = count($data);

foreach ($data AS $result_item) {foreach ($data AS $result_item) { $result = $rest->appendElement('result');$result = $rest->appendElement('result'); $result->appendElement('title', $result_item['title']);$result->appendElement('title', $result_item['title']); $result->appendElement('description', $result_item['descript']);$result->appendElement('description', $result_item['descript']);}}

print $rest->asXML();print $rest->asXML();

Page 46: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Advanced Editing SimpleXML: Advanced Editing ResultsResults

<?xml version="1.0"?><?xml version="1.0"?><results num="3"><results num="3"> <result><result> <title>Result 1</title><title>Result 1</title> <description>Res1 description</description><description>Res1 description</description> </result></result> <result><result> <title>Result 2</title><title>Result 2</title> <description>description of Res2</description><description>description of Res2</description> </result></result> <result><result> <title>Result 3</title><title>Result 3</title> <description>This is result 3</description><description>This is result 3</description> </result></result></results></results>

Page 47: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Advanced Editing SimpleXML: Advanced Editing PHP 5.1.3PHP 5.1.3

simplexml/editing_php513.phpsimplexml/editing_php513.php

$data = array(array('title'=>'Result 1', 'descript'=>'Res1 description'),$data = array(array('title'=>'Result 1', 'descript'=>'Res1 description'), array('title'=>'Result 2', 'descript'=>'description of Res2'),array('title'=>'Result 2', 'descript'=>'description of Res2'), array('title'=>'Result 3', 'descript'=>'This is result 3'));array('title'=>'Result 3', 'descript'=>'This is result 3'));

$rest = simplexml_load_string('<results num="0" />');$rest = simplexml_load_string('<results num="0" />');$rest['num'] = count($data);$rest['num'] = count($data);

foreach ($data AS $result_item) {foreach ($data AS $result_item) { $result = $rest->$result = $rest->addChildaddChild('result');('result'); $result->$result->addChildaddChild('title', $result_item['title']);('title', $result_item['title']); $result->$result->addChildaddChild('description');('description'); $result->description = $result_item['descript'];$result->description = $result_item['descript'];}}

print $rest->asXML();print $rest->asXML();

Page 48: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Removing data SimpleXML: Removing data remove_data.phpremove_data.php

<?php<?php$results = simplexml_load_file('editing_php513.xml');$results = simplexml_load_file('editing_php513.xml');

/* Delete title from first result element *//* Delete title from first result element */unset($results->result->title);unset($results->result->title);

/* Delete the 2nd result element - WORKS in PHP 5.1.3+ *//* Delete the 2nd result element - WORKS in PHP 5.1.3+ */unset($results->result[1]);unset($results->result[1]);

print $results->asXML();print $results->asXML();?>?>

Page 49: Advanced XML with PHP 5 - CDATA Zone

SimpleXML: Removing data SimpleXML: Removing data RESULTSRESULTS

<?xml version="1.0"?><?xml version="1.0"?>

<results num="3"><results num="3">

<result><result>

<description>Res1 description</description><description>Res1 description</description>

</result></result>

<result><result>

<title>Result 3</title><title>Result 3</title>

<description>This is result 3</description><description>This is result 3</description>

</result></result>

</results></results>

Page 50: Advanced XML with PHP 5 - CDATA Zone

SDO (SDO_DAS_XML)SDO (SDO_DAS_XML)

� Provides simple access to XML documentsProvides simple access to XML documents� Works in a similar fashion to SimpleXMLWorks in a similar fashion to SimpleXML� Operates only on elements and attributesOperates only on elements and attributes� Contains XPath supportContains XPath support� Allows for modifications to the XMLAllows for modifications to the XML� Requires XML SchemaRequires XML Schema� Stricter than SimpleXMLStricter than SimpleXML� Maps XML to Data TypesMaps XML to Data Types

Page 51: Advanced XML with PHP 5 - CDATA Zone

SDO: Consuming Yahoo ContextSearch SDO: Consuming Yahoo ContextSearch sdo/yahoo_search_results.xmlsdo/yahoo_search_results.xml

<ResultSet <ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" totalResultsReturnedtotalResultsReturned="3" firstResultPosition="1">="3" firstResultPosition="1">

<<ResultResult>> <<TitleTitle>Zend Technologies - PHP 5 . . .</Title>>Zend Technologies - PHP 5 . . .</Title> <Summary>titletext = $dom-&amp;gt;createText. . .</Summary><Summary>titletext = $dom-&amp;gt;createText. . .</Summary> <<UrlUrl >http://www.zend.com/php5/articles/php5-x. . .</Url>>http://www.zend.com/php5/articles/php5-x. . .</Url> <ClickUrl>http://uk.wrs.yahoo.com/_ylt=...</ClickUrl><ClickUrl>http://uk.wrs.yahoo.com/_ylt=...</ClickUrl> <<ModificationDateModificationDate>1171872000</ModificationDate>>1171872000</ModificationDate> <MimeType>text/html</MimeType><MimeType>text/html</MimeType> <!-- Abbreviated Content --><!-- Abbreviated Content --> </Result></Result>

<!-- Abbreviated Response --><!-- Abbreviated Response --></ResultSet></ResultSet>

Page 52: Advanced XML with PHP 5 - CDATA Zone

SDO: Consuming Yahoo ContextSearchSDO: Consuming Yahoo ContextSearchsdosdo/yahoo_search.php/yahoo_search.php

/* URL to Web Search service *//* URL to Web Search service */$url = 'http://search.yahooapis.com/WebSearchService/V1/contextSearch';$url = 'http://search.yahooapis.com/WebSearchService/V1/contextSearch';$url .= '?query='.rawurlencode('php5 xml')."&appid=zzz&results=3&language=en&context=internet";$url .= '?query='.rawurlencode('php5 xml')."&appid=zzz&results=3&language=en&context=internet";

$xsd = "http://search.yahooapis.com/WebSearchService/V1/WebSearchResponse.xsd";$xsd = "http://search.yahooapis.com/WebSearchService/V1/WebSearchResponse.xsd";$xmldas = SDO_DAS_XML::create($xsd);$xmldas = SDO_DAS_XML::create($xsd);

$document = $xmldas->loadFile($url);$document = $xmldas->loadFile($url);

$sxe = $document->getRootDataObject();$sxe = $document->getRootDataObject();

/* Check for number of results returned *//* Check for number of results returned */if ((int)$sxe['totalResultsReturned'] > 0) {if ((int)$sxe['totalResultsReturned'] > 0) {

/* Loop through results and print title, url and modification date *//* Loop through results and print title, url and modification date */ foreach ($sxe->Result AS $result) {foreach ($sxe->Result AS $result) { print 'Title: '.$result->Title."\n";print 'Title: '.$result->Title."\n"; print 'Url: '.$result->Url."\n";print 'Url: '.$result->Url."\n"; print 'Mod Date: '.date ('M d Y', (int)$result->ModificationDate)."\n\n";print 'Mod Date: '.date ('M d Y', (int)$result->ModificationDate)."\n\n"; }}}}

Page 53: Advanced XML with PHP 5 - CDATA Zone

SDO: Consuming Yahoo ContextSearchSDO: Consuming Yahoo ContextSearchsdosdo/yahoo_search2.php/yahoo_search2.php

/* URL to Web Search service *//* URL to Web Search service */$url = 'http://search.yahooapis.com/WebSearchService/V1/contextSearch';$url = 'http://search.yahooapis.com/WebSearchService/V1/contextSearch';$url .= '?query='.rawurlencode('php5 xml')."&appid=zzz&results=3&language=en&context=internet";$url .= '?query='.rawurlencode('php5 xml')."&appid=zzz&results=3&language=en&context=internet";

$xsd = "http://search.yahooapis.com/WebSearchService/V1/WebSearchResponse.xsd";$xsd = "http://search.yahooapis.com/WebSearchService/V1/WebSearchResponse.xsd";$xmldas = SDO_DAS_XML::create($xsd);$xmldas = SDO_DAS_XML::create($xsd);

$document = $xmldas->loadFile($url);$document = $xmldas->loadFile($url);

$sxe = $document->getRootDataObject();$sxe = $document->getRootDataObject();

/* Check for number of results returned *//* Check for number of results returned */if (if ($sxe->totalResultsReturned$sxe->totalResultsReturned > 0) { > 0) {

/* Loop through results and print title, url and modification date *//* Loop through results and print title, url and modification date */ foreach ($sxe->Result AS $result) {foreach ($sxe->Result AS $result) { print 'Title: '.$result->Title."\n";print 'Title: '.$result->Title."\n"; print 'Url: '.$result->Url."\n";print 'Url: '.$result->Url."\n"; print 'Mod Date: '.date ('M d Y', print 'Mod Date: '.date ('M d Y', $result->ModificationDate$result->ModificationDate)."\n\n";)."\n\n"; }}}}

Page 54: Advanced XML with PHP 5 - CDATA Zone

SDO: Consuming Yahoo ContextSearch SDO: Consuming Yahoo ContextSearch RESULTSRESULTS

Title: Zend Technologies - PHP 5 In Depth - XML in PHP 5 - What's New?Title: Zend Technologies - PHP 5 In Depth - XML in PHP 5 - What's New?Url: http://www.zend.com/php5/articles/php5-xmlphp.phpUrl: http://www.zend.com/php5/articles/php5-xmlphp.phpMod Date: Feb 19 2007Mod Date: Feb 19 2007

Title: Zend Developer Zone | XML in PHP 5 - What's New?Title: Zend Developer Zone | XML in PHP 5 - What's New?Url: http://devzone.zend.com/node/view/id/1713Url: http://devzone.zend.com/node/view/id/1713Mod Date: Feb 26 2007Mod Date: Feb 26 2007

Title: Parsing XML using PHP5Title: Parsing XML using PHP5Url: http://www.developertutorials.com/tutorials/php/parsing-xml-using-Url: http://www.developertutorials.com/tutorials/php/parsing-xml-using-

php5-050816/page1.htmlphp5-050816/page1.htmlMod Date: Feb 02 2007Mod Date: Feb 02 2007

Page 55: Advanced XML with PHP 5 - CDATA Zone

SDO: XML EditingSDO: XML Editingsdo/address.xsdsdo/address.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema"<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:addr="urn::addressNS" targetNamespace="urn::addressNS" xmlns:addr="urn::addressNS" targetNamespace="urn::addressNS" elementFormDefault="qualified">elementFormDefault="qualified">

<complexType name="AddressType"><complexType name="AddressType"> <sequence><sequence> <element name="street" type="string"/><element name="street" type="string"/> <element name="city" type="string"/><element name="city" type="string"/> <element name="state" type="string"/><element name="state" type="string"/> <element name="zip" type="string"/><element name="zip" type="string"/> </sequence></sequence> </complexType></complexType>

<element name="address" type="addr:AddressType" /><element name="address" type="addr:AddressType" /> </schema></schema>

Page 56: Advanced XML with PHP 5 - CDATA Zone

SDO: XML EditingSDO: XML Editingsdo/editing.phpsdo/editing.php

$xmldas = SDO_DAS_XML::create("address.xsd");$xmldas = SDO_DAS_XML::create("address.xsd");$xdoc = $xmldas->createDocument();$xdoc = $xmldas->createDocument();$address = $xdoc->getRootDataObject();$address = $xdoc->getRootDataObject();

$address->street = "123 My Street";$address->street = "123 My Street";$address->zip = 12345;$address->zip = 12345;$address->state = 'ME';$address->state = 'ME';$address->city = 'Portland';$address->city = 'Portland';

print $xmldas->saveString($xdoc, 5);print $xmldas->saveString($xdoc, 5);

<?xml version="1.0" encoding="UTF-8"?><?xml version="1.0" encoding="UTF-8"?><address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="urn::addressNS" xmlns="urn::addressNS">xmlns:tns="urn::addressNS" xmlns="urn::addressNS"> <street>123 My Street</street><street>123 My Street</street> <city>Portland</city><city>Portland</city> <state>ME</state><state>ME</state> <zip>12345</zip><zip>12345</zip></address></address>

Page 57: Advanced XML with PHP 5 - CDATA Zone

SDO: XML EditingSDO: XML Editingsdo/editing_error.phpsdo/editing_error.php

try {try { $xmldas = SDO_DAS_XML::create("address.xsd");$xmldas = SDO_DAS_XML::create("address.xsd"); $xdoc = $xmldas->createDocument("$xdoc = $xmldas->createDocument("addressaddress");"); $address = $xdoc->getRootDataObject();$address = $xdoc->getRootDataObject();

$address->city = "Portland";$address->city = "Portland"; $address->$address->companycompany = "Local Thunder"; = "Local Thunder"; print($xmldas->saveString($xdoc, 5));print($xmldas->saveString($xdoc, 5));} catch (SDO_Exception $e) {} catch (SDO_Exception $e) { print "Error: ".$e->getMessage()."\n";print "Error: ".$e->getMessage()."\n";}}

Error: Cannot find property:companyError: Cannot find property:company

Page 58: Advanced XML with PHP 5 - CDATA Zone

DOMDOM

� Tree based parserTree based parser� Allows for creation and editing of XML documentsAllows for creation and editing of XML documents� W3C Specification with DOM Level 2/3 compliancyW3C Specification with DOM Level 2/3 compliancy� Provides XPath supportProvides XPath support� Provides XInclude SupportProvides XInclude Support� Ability to work with HTML documentsAbility to work with HTML documents� Zero copy interoperability with SimpleXMLZero copy interoperability with SimpleXML� Replacement for ext/domxml from PHP 4Replacement for ext/domxml from PHP 4

Page 59: Advanced XML with PHP 5 - CDATA Zone

DOMNode ClassesDOMNode Classes� DOMDocumentDOMDocument� DOMElementDOMElement� DOMAttrDOMAttr� DOMCommentDOMComment� DOMDocumentTypeDOMDocumentType� DOMNotationDOMNotation� DOMEntityDOMEntity

� DOMEntityReferenceDOMEntityReference� DOMProcessingInstructionDOMProcessingInstruction� DOMNameSpaceNodeDOMNameSpaceNode� DOMDocumentFragmentDOMDocumentFragment� DOMCharacterDataDOMCharacterData� DOMTextDOMText� DOMCdataSectionDOMCdataSection

�DOMException�DOMImplementation

�DOMNodeList�DOMNamedNodeMap�DOMXPath

Additional Classes

Page 60: Advanced XML with PHP 5 - CDATA Zone

DOM: Sample DocumentDOM: Sample Document<courses><courses> <course cid="c1"><course cid="c1"> <title>Basic Languages</title><title>Basic Languages</title> <description>Introduction to Languages</description><description>Introduction to Languages</description> <credits>1.5</credits><credits>1.5</credits> <lastmodified>2004-09-01T11:13:01</lastmodified><lastmodified>2004-09-01T11:13:01</lastmodified> </course></course> <course cid="c2"><course cid="c2"> <title>French I</title><title>French I</title> <description>Introduction to French</description><description>Introduction to French</description> <credits>3.0</credits><credits>3.0</credits> <lastmodified>2005-06-01T14:21:37</lastmodified><lastmodified>2005-06-01T14:21:37</lastmodified> </course></course> <course cid="c3"><course cid="c3"> <title>French II</title><title>French II</title> <description>Intermediate French</description><description>Intermediate French</description> <credits>3.0</credits><credits>3.0</credits> <lastmodified>2005-03-12T15:45:44</lastmodified><lastmodified>2005-03-12T15:45:44</lastmodified> </course></course></courses></courses>

Page 61: Advanced XML with PHP 5 - CDATA Zone

DOM:Document NavigationDOM:Document Navigationdom/navigate-2.phpdom/navigate-2.php

<?php$dom = new DOMDocument();$dom->load('course.xml');

$nodelist = $dom->getElementsByTagName('description');

foreach ($nodelist AS $key=>$node) { print "#$key: ".$node->nodeValue."\n";}?>

Results:

#0: Introduction to Languages#1: Introduction to French#2: Intermediate French

Page 62: Advanced XML with PHP 5 - CDATA Zone

DOM: Navigation OptimizedDOM: Navigation Optimizeddom/navigate-optimized.phpdom/navigate-optimized.php

function locateDescription($node) {function locateDescription($node) { while($node) {while($node) { if ($node->nodeType if ($node->nodeType == XML_ELEMENT_NODE &&== XML_ELEMENT_NODE && $node->nodeName $node->nodeName ==== 'description') { 'description') { $GLOBALS['arNodeSet'][] = $node;$GLOBALS['arNodeSet'][] = $node; return;return; }} locateDescription($node->firstChild);locateDescription($node->firstChild); $node = $node->nextSibling;$node = $node->nextSibling; }}}}

$dom = new DOMDocument();$dom = new DOMDocument();$dom->load('course.xml');$dom->load('course.xml');$root = $dom->documentElement;$root = $dom->documentElement;$arNodeSet = array();$arNodeSet = array();

locateDescription($root->firstChild);locateDescription($root->firstChild);

foreach ($arNodeSet AS $key=>$node) {foreach ($arNodeSet AS $key=>$node) { print "#$key: ".$node->nodeValue."\n";print "#$key: ".$node->nodeValue."\n";}}

Page 63: Advanced XML with PHP 5 - CDATA Zone

DOM: Creating a Simple TreeDOM: Creating a Simple Treedom/create_simple_tree.phpdom/create_simple_tree.php

$doc = new DOMDocument();$doc = new DOMDocument();

$root = $doc->createElement("tree");$root = $doc->createElement("tree");$doc->appendChild($root);$doc->appendChild($root);

$root->setAttribute("att1", "att1 value");$root->setAttribute("att1", "att1 value");

$attr2 = $doc->createAttribute("att2");$attr2 = $doc->createAttribute("att2");$attr2->appendChild($doc->createTextNode("att2 value"));$attr2->appendChild($doc->createTextNode("att2 value"));$root->setAttributeNode($attr2);$root->setAttributeNode($attr2);

$child = $root->appendChild(new DOMElement("child"));$child = $root->appendChild(new DOMElement("child"));

$comment = $doc->createComment("My first Document");$comment = $doc->createComment("My first Document");$doc->insertBefore($comment, $root);$doc->insertBefore($comment, $root);

$pi = $doc->createProcessingInstruction("php", 'echo "Hello World!"');$pi = $doc->createProcessingInstruction("php", 'echo "Hello World!"');$root->appendChild($pi);$root->appendChild($pi);

$cdata = $doc->createCdataSection("special chars: & < > '");$cdata = $doc->createCdataSection("special chars: & < > '");$child->appendChild($cdata);$child->appendChild($cdata);

Page 64: Advanced XML with PHP 5 - CDATA Zone

DOM: Simple Tree OutputDOM: Simple Tree Output

<?xml version="1.0"?><!--My first Document--><tree att1="att1 value" att2="att2 value"> <child><![CDATA[special chars: & < > ']]></child><?php echo "Hello World!"?></tree>

Page 65: Advanced XML with PHP 5 - CDATA Zone

DOM: ModificationDOM: ModificationLoad with User StreamLoad with User Stream

class MyStreamWrapper {class MyStreamWrapper { protected $stream = 'protected $stream = '<!--My first Document--><tree att1="att1 value" att2="att2 value"> <!--My first Document--><tree att1="att1 value" att2="att2 value">

<child><![CDATA[special chars: & < > ]]></child><?php echo "Hello World!"?></tree>';<child><![CDATA[special chars: & < > ]]></child><?php echo "Hello World!"?></tree>';

public function stream_open($path, $mode, $options, $opened_path) {public function stream_open($path, $mode, $options, $opened_path) { $this->position = 0;$this->position = 0; $this->len = strlen($this->stream);$this->len = strlen($this->stream); return true;return true; }}

public function stream_read($count) {public function stream_read($count) { $ret = substr($this->stream, $this->position, $count);$ret = substr($this->stream, $this->position, $count); $this->position += strlen($ret);$this->position += strlen($ret); return $ret;return $ret; }}

public function stream_close() { }public function stream_close() { } public function stream_eof() { return $this->position >= $this->len; }public function stream_eof() { return $this->position >= $this->len; } public function stream_stat() { return $this->len; }public function stream_stat() { return $this->len; } public function url_stat($path) { return array($this->len); }public function url_stat($path) { return array($this->len); }}}stream_wrapper_register('myStream', 'MyStreamWrapper');stream_wrapper_register('myStream', 'MyStreamWrapper');

Page 66: Advanced XML with PHP 5 - CDATA Zone

DOM: Document ModificationDOM: Document Modificationdom/modify.phpdom/modify.php

<!--My first Document--><!--My first Document--><tree att1="att1 value" att2="att2 value"><child><![CDATA[special chars: & < > ]]></child><tree att1="att1 value" att2="att2 value"><child><![CDATA[special chars: & < > ]]></child><?php echo "Hello World!"?><?php echo "Hello World!"?></tree></tree>

$doc = new DOMDocument();$doc = new DOMDocument();$doc->load('myStream://myData');$doc->load('myStream://myData');$tree = $doc->documentElement;$tree = $doc->documentElement;

$tree->setAttribute("att1", "new val");$tree->setAttribute("att1", "new val");$tree->removeAttribute("att2");$tree->removeAttribute("att2");

foreach ($tree->childNodes AS $child) {foreach ($tree->childNodes AS $child) { if ($child->nodeName == 'child') {if ($child->nodeName == 'child') { $child->replaceChild(new DOMText("new Content"), $child->firstChild);$child->replaceChild(new DOMText("new Content"), $child->firstChild); break;break; }}}}

print $doc->saveXML();print $doc->saveXML();

<!--My first Document--><!--My first Document--><tree att1="new val"> <child>new Content</child><?php echo "Hello World!"?></tree><tree att1="new val"> <child>new Content</child><?php echo "Hello World!"?></tree>

Page 67: Advanced XML with PHP 5 - CDATA Zone

DOM: Document ModificationDOM: Document Modification/* Remove all children of an element *//* Remove all children of an element */

while ($entry->hasChildNodes()) {while ($entry->hasChildNodes()) { $entry->removeChild($entry->firstChild);$entry->removeChild($entry->firstChild);}}

OROR

$node = $entry->lastChild;$node = $entry->lastChild;while($node) {while($node) { $prev = $node->previousSibling;$prev = $node->previousSibling; $entry->removeChild($node);$entry->removeChild($node); $node = $prev;$node = $prev;}}

/* This Will Not Work! *//* This Will Not Work! */foreach($entry->childNodes AS $node) {foreach($entry->childNodes AS $node) { $entry->removeChild($node);$entry->removeChild($node);}}

/* These will work */ $children = $entry->childNodes; $length = $children->length - 1;

for ($x=$length; $x >=0; $x--) { $entry->removeChild($children->item($x));}

OR

$elem = $entry->cloneNode(FALSE);$entry->parentNode->replaceChild($elem, $entry);

Page 68: Advanced XML with PHP 5 - CDATA Zone

DOM and NamespacesDOM and Namespaces

<xsd:complexType <xsd:complexType xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" name="ArrayOfint">name="ArrayOfint"> <xsd:complexContent><xsd:complexContent> <xsd:restriction base="soapenc:Array"><xsd:restriction base="soapenc:Array"> <xsd:attribute ref="soapenc:arrayType" <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:int[ ]"wsdl:arrayType="xsd:int[ ]"/>/> </xsd:restriction></xsd:restriction> </xsd:complexContent></xsd:complexContent></xsd:complexType></xsd:complexType>

Page 69: Advanced XML with PHP 5 - CDATA Zone

Dom and NamepsacesDom and Namepsacesdom/namespace.phpdom/namespace.php

define("SCHEMA_NS", "http://www.w3.org/2001/XMLSchema");define("SCHEMA_NS", "http://www.w3.org/2001/XMLSchema");define("WSDL_NS", "http://schemas.xmlsoap.org/wsdl/");define("WSDL_NS", "http://schemas.xmlsoap.org/wsdl/");$dom = new DOMDocument();$dom = new DOMDocument();

$root = $dom->createElementNS(SCHEMA_NS, "xsd:complexType");$root = $dom->createElementNS(SCHEMA_NS, "xsd:complexType");$dom->appendChild($root);$dom->appendChild($root);

$root->setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:wsdl", WSDL_NS);$root->setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:wsdl", WSDL_NS);$root->setAttribute("name", "ArrayOfint");$root->setAttribute("name", "ArrayOfint");

$content = $root->appendChild($content = $root->appendChild(new DOMElement("xsd:complexContent", NULL, new DOMElement("xsd:complexContent", NULL, SCHEMA_NS)SCHEMA_NS)););

$restriction = $content->appendChild($restriction = $content->appendChild(new DOMElement("xsd:restriction", NULL, new DOMElement("xsd:restriction", NULL, SCHEMA_NS)SCHEMA_NS)););

$restriction->setAttribute("base", "soapenc:Array");$restriction->setAttribute("base", "soapenc:Array");

$attribute = $restriction->appendChild($attribute = $restriction->appendChild(new DOMElement("xsd:attribute", NULL, new DOMElement("xsd:attribute", NULL, SCHEMA_NS)SCHEMA_NS)););

$attribute->setAttribute("ref", "soapenc:arrayType");$attribute->setAttribute("ref", "soapenc:arrayType");

$attribute->setAttributeNS(WSDL_NS, "wsdl:arrayType ", "xsd:int[]");$attribute->setAttributeNS(WSDL_NS, "wsdl:arrayType ", "xsd:int[]");

Page 70: Advanced XML with PHP 5 - CDATA Zone

DOM and XpathDOM and Xpathdom/xpath/dom-xpath.xmldom/xpath/dom-xpath.xml

<books xmlns="http://www.example.com/books"<books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book">xmlns:bk="http://www.example.com/book"> <bk:book qty="25"><bk:book qty="25"> <bk:name>Grapes of Wrath</bk:name><bk:name>Grapes of Wrath</bk:name> <bk:price>12.99</bk:price><bk:price>12.99</bk:price> </bk:book></bk:book>

<book qty="33" xmlns="http://www.example.com/ExteralClassics"><book qty="33" xmlns="http://www.example.com/ExteralClassics"> <name>To Kill a Mockingbird</name><name>To Kill a Mockingbird</name> <price>10.99</price><price>10.99</price> </book></book></books></books>

Page 71: Advanced XML with PHP 5 - CDATA Zone

DOM and XpathDOM and Xpathdom/xpath/dom-xpath.phpdom/xpath/dom-xpath.php

<books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"><books xmlns="http://www.example.com/books" xmlns:bk="http://www.example.com/book"> <bk:book qty="25"><bk:book qty="25"> <bk:name>Grapes of Wrath</bk:name></bk:book><bk:name>Grapes of Wrath</bk:name></bk:book> <book qty="33" xmlns="http://www.example.com/ExteralClassics"><book qty="33" xmlns="http://www.example.com/ExteralClassics"> <name>To Kill a Mockingbird</name></book><name>To Kill a Mockingbird</name></book></books></books>

$xpath = $xpath = new DOMXPath($doc);new DOMXPath($doc);

$nodelist = $xpath->$nodelist = $xpath->queryquery("//bk:name");("//bk:name");print "Book Title: ".$nodelist->item($nodelist->length - 1)->textContent."\n";print "Book Title: ".$nodelist->item($nodelist->length - 1)->textContent."\n";

$inventory = $xpath->$inventory = $xpath->evaluateevaluate("sum(//@qty)");("sum(//@qty)");print "Total Books: ".$inventory."\n";print "Total Books: ".$inventory."\n";

$xpath->registerNameSpace("ec", "http://www.example.com/ExteralClassics");$xpath->registerNameSpace("ec", "http://www.example.com/ExteralClassics");$nodelist = $xpath->$nodelist = $xpath->queryquery("//ec:book");("//ec:book");

$book = $nodelist->item(0);$book = $nodelist->item(0);$inventory = $xpath->$inventory = $xpath->evaluateevaluate("sum(./@qty)", ("sum(./@qty)", $book$book););print "Total Books: ".$inventory."\n";print "Total Books: ".$inventory."\n";

Page 72: Advanced XML with PHP 5 - CDATA Zone

DOM and Xpath ResultsDOM and Xpath ResultsBook Title: Grapes of WrathBook Title: Grapes of WrathTotal Books: 58Total Books: 58Total Books: 33Total Books: 33

Page 73: Advanced XML with PHP 5 - CDATA Zone

Performing ValidationPerforming Validationdom/validation/validate.phpdom/validation/validate.php

$doc = new DOMDocument();$doc = new DOMDocument();print "DTD Validation:\n";print "DTD Validation:\n";$doc->load('courses-dtd.xml', LIBXML_DTDVALID);$doc->load('courses-dtd.xml', LIBXML_DTDVALID);/* No errors means document is valid *//* No errors means document is valid */

if ($doc->validate()) { print " Document Is Valid\n"; }if ($doc->validate()) { print " Document Is Valid\n"; }

print "DTD Validation FAILURE:\n";print "DTD Validation FAILURE:\n";$doc->load('course-id.xml');$doc->load('course-id.xml');if (if ($doc->validate()$doc->validate()) { print " Document Is Valid\n"; }) { print " Document Is Valid\n"; }

$doc->load('course.xml');$doc->load('course.xml');print "\nXML Schema Validation:\n";print "\nXML Schema Validation:\n";if (if ($doc->schemaValidate('course.xsd')$doc->schemaValidate('course.xsd')) { print " Document is valid\n"; }) { print " Document is valid\n"; }

$doc->load('course.xml');$doc->load('course.xml');print "\nRelaxNG Validation:\n";print "\nRelaxNG Validation:\n";if (if ($doc->relaxNGValidate('course.rng')$doc->relaxNGValidate('course.rng')) { print " Document is valid\n"; ) { print " Document is valid\n";

} }

Page 74: Advanced XML with PHP 5 - CDATA Zone

Performing Validation ResultsPerforming Validation ResultsDTD Validation:DTD Validation: Document Is ValidDocument Is Valid

DTD Validation FAILURE:DTD Validation FAILURE:Warning: DOMDocument::validate(): No declaration for element courses in Warning: DOMDocument::validate(): No declaration for element courses in

/home/rrichards/workshop/dom/validation/validate.php on line 11/home/rrichards/workshop/dom/validation/validate.php on line 11Warning: DOMDocument::validate(): No declaration for element course in Warning: DOMDocument::validate(): No declaration for element course in

/home/rrichards/workshop/dom/validation/validate.php on line 11/home/rrichards/workshop/dom/validation/validate.php on line 11Warning: DOMDocument::validate(): No declaration for element title in Warning: DOMDocument::validate(): No declaration for element title in

/home/rrichards/workshop/dom/validation/validate.php on line 11/home/rrichards/workshop/dom/validation/validate.php on line 11. . .. . .

XML Schema Validation:XML Schema Validation: Document is validDocument is valid

RelaxNG Validation:RelaxNG Validation: Document is validDocument is valid

Page 75: Advanced XML with PHP 5 - CDATA Zone

Extending DOM ClassesExtending DOM Classes

� Overriding the constructor requires the parent Overriding the constructor requires the parent constructor to be called.constructor to be called.

� Properties built into the DOM classes cannot Properties built into the DOM classes cannot be overridden.be overridden.

� Methods built into the DOM classes may can Methods built into the DOM classes may can be overridden.be overridden.

� The lifespan of an extended object is that of The lifespan of an extended object is that of the object itself.the object itself.

Page 76: Advanced XML with PHP 5 - CDATA Zone

Extending DOM Classes Extending DOM Classes dom/extending/dom/extending/extending.phpextending.php

class customElement extends DOMElement { }class customElement extends DOMElement { }

class customDoc extends DOMDocument {class customDoc extends DOMDocument { public $nodeName = "customDoc";public $nodeName = "customDoc";

function __construct($rootName) {function __construct($rootName) { parent::__construct();parent::__construct(); if (! empty($rootName))if (! empty($rootName)) $element = $this->appendChild(new DOMElement($rootName));$element = $this->appendChild(new DOMElement($rootName)); }}

function createElement($name, $value, $parent=NULL) {function createElement($name, $value, $parent=NULL) { $custom = new customElement($name, $value);$custom = new customElement($name, $value); if ($parent && ($parent instanceof DOMElement)) { if ($parent && ($parent instanceof DOMElement)) { $parent->appendChild($custom); }$parent->appendChild($custom); } return $custom;return $custom; }}}}

$myc = new customDoc("root");$myc = new customDoc("root");$myelement = $myc->createElement("myname", "value", $myc->documentElement);$myelement = $myc->createElement("myname", "value", $myc->documentElement);if ($myelement instanceof customElement) { print "This is a customElement\n"; }if ($myelement instanceof customElement) { print "This is a customElement\n"; }

print $myc->nodeName."\n";print $myc->nodeName."\n";print $myc->saveXML();print $myc->saveXML();

Page 77: Advanced XML with PHP 5 - CDATA Zone

DOM Object ScopeDOM Object Scopedom/extending/object_scope.phpdom/extending/object_scope.php

class customElement extends DOMElement { }class customElement extends DOMElement { }

function changeit($doc) {function changeit($doc) { $myelement$myelement = new customElement("custom", "element2"); = new customElement("custom", "element2");

$doc->replaceChild($myelement, $doc->documentElement);$doc->replaceChild($myelement, $doc->documentElement);print "Within changeit function: ".get_class($doc->documentElement)."\n";print "Within changeit function: ".get_class($doc->documentElement)."\n";

}}

$doc = new DOMDocument();$doc = new DOMDocument();

$myelement$myelement = $doc->appendChild(new customElement("custom", "element")); = $doc->appendChild(new customElement("custom", "element"));print "After Append: ".get_class($myelement)."\n";print "After Append: ".get_class($myelement)."\n";

unset($myelement);unset($myelement);print "After unset: ".get_class($doc->documentElement)."\n";print "After unset: ".get_class($doc->documentElement)."\n";

changeit($doc);changeit($doc);print "Outside changeit(): ".get_class($doc->documentElement)."\n";print "Outside changeit(): ".get_class($doc->documentElement)."\n";

After Append: customElementAfter Append: customElementAfter unset: DOMElementAfter unset: DOMElementWithin changeit function: customElementWithin changeit function: customElementOutside changeit(): DOMElementOutside changeit(): DOMElement

Page 78: Advanced XML with PHP 5 - CDATA Zone

DOM: registerNodeClassDOM: registerNodeClass dom/extending/register_node_class.php dom/extending/register_node_class.php

class customElement extends DOMElement { }class customElement extends DOMElement { }function changeit($doc) {function changeit($doc) { $myelement$myelement = new DOMElement("custom", "element2"); = new DOMElement("custom", "element2");

$doc->replaceChild($myelement, $doc->documentElement);$doc->replaceChild($myelement, $doc->documentElement);print "Within changeit function: ".get_class($doc->documentElement)."\n";print "Within changeit function: ".get_class($doc->documentElement)."\n";

}}

$doc = new DOMDocument();$doc = new DOMDocument();$doc->registerNodeClass('DOMElement', 'customElement');$doc->registerNodeClass('DOMElement', 'customElement');

$myelement$myelement = $doc->appendChild($doc->createElement("custom", "element")); = $doc->appendChild($doc->createElement("custom", "element"));print "After Append: ".get_class($myelement)."\n";print "After Append: ".get_class($myelement)."\n";

unset($myelement);unset($myelement);print "After unset: ".get_class($doc->documentElement)."\n";print "After unset: ".get_class($doc->documentElement)."\n";

changeit($doc);changeit($doc);print "Outside changeit(): ".get_class($doc->documentElement)."\n";print "Outside changeit(): ".get_class($doc->documentElement)."\n";

After Append: customElementAfter Append: customElementAfter unset: customElementAfter unset: customElementWithin changeit function: DOMElementWithin changeit function: DOMElementOutside changeit(): customElementOutside changeit(): customElement

Page 79: Advanced XML with PHP 5 - CDATA Zone

DOM:Common IssuesDOM:Common Issues

� DOM Objects and SessionsDOM Objects and Sessions� Removing Nodes while iterating a Nodeset skips Removing Nodes while iterating a Nodeset skips

nodesnodes� XML Tree contains garbled charactersXML Tree contains garbled characters� Extended class is not returned from property or Extended class is not returned from property or

methodmethod� Elements not being returned by IDElements not being returned by ID� Entity errors are issues when loading a documentEntity errors are issues when loading a document� New DTD is not recognized by documentNew DTD is not recognized by document

Page 80: Advanced XML with PHP 5 - CDATA Zone

XMLReaderXMLReader

� Forward moving stream based parserForward moving stream based parser� It is a Pull parserIt is a Pull parser� Based on the C# XmlTextReader APIBased on the C# XmlTextReader API� Advantages:Advantages:

� Low memory footprintLow memory footprint� Namespace supportNamespace support� Simple APISimple API� Validation supportValidation support� Advanced Feature SetAdvanced Feature Set� Faster ProcessingFaster Processing

Page 81: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Simple ExampleXMLReader: Simple Examplexmlreader/reader_simple.xmlxmlreader/reader_simple.xml

<?xml version='1.0'?><?xml version='1.0'?><chapter xmlns:a="http://www.example.com/namespace-a"<chapter xmlns:a="http://www.example.com/namespace-a" xmlns="http://www.example.com/default">xmlns="http://www.example.com/default"> <a:title>XMLReader</a:title><a:title>XMLReader</a:title> <para><para> First ParagraphFirst Paragraph </para></para> <a:section a:id="about"><a:section a:id="about"> <title>About this Document</title><title>About this Document</title> <para><para> <!-- this is a comment --><!-- this is a comment --> <?php echo 'Hi! This is PHP version ' . phpversion(); ?><?php echo 'Hi! This is PHP version ' . phpversion(); ?> </para></para> </a:section></a:section></chapter></chapter>

Page 82: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Simple ExampleXMLReader: Simple Examplexmlreader/reader_simple.phpxmlreader/reader_simple.php

$reader = new XMLReader();$reader = new XMLReader();$reader->open('reader_simple.xml');$reader->open('reader_simple.xml');$reader->read();$reader->read();

print "xmlns Attribute value: ".$reader->getAttributeNo(0)."\n\n";print "xmlns Attribute value: ".$reader->getAttributeNo(0)."\n\n";

while ($reader->read() && $reader->name != "a:title") { }while ($reader->read() && $reader->name != "a:title") { }print "Local Name for Element: ".$reader->localName."\n";print "Local Name for Element: ".$reader->localName."\n";print "Namespace URI for Element: ".$reader->namespaceURI."\n";print "Namespace URI for Element: ".$reader->namespaceURI."\n";

while($reader->read()) {while($reader->read()) { switch ($reader->nodeType) {switch ($reader->nodeType) { case XMLReader::ELEMENT:case XMLReader::ELEMENT: print "Element: ".$reader->name."\n";print "Element: ".$reader->name."\n"; if ($reader->hasAttributes && $reader->moveToFirstAttribute()) {if ($reader->hasAttributes && $reader->moveToFirstAttribute()) { do {do { print " ".$reader->name."=".$reader->value."\n";print " ".$reader->name."=".$reader->value."\n"; } while($reader->moveToNextAttribute());} while($reader->moveToNextAttribute()); }} break;break; case XMLReader::PI:case XMLReader::PI: print "PI Target: ".$reader->name."\n PI Data: ".$reader->value."\n";print "PI Target: ".$reader->name."\n PI Data: ".$reader->value."\n"; }}}}

Page 83: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Simple ExampleXMLReader: Simple ExampleRESULTSRESULTS

xmlns Attribute value: http://www.example.com/namespace-axmlns Attribute value: http://www.example.com/namespace-a

Local Name for Element: titleLocal Name for Element: titleNamespace URI for Element: Namespace URI for Element: http://www.example.com/namespace-ahttp://www.example.com/namespace-a

Element: paraElement: paraElement: a:sectionElement: a:section a:id=abouta:id=aboutElement: titleElement: titleElement: paraElement: paraPI Target: phpPI Target: php PI Data: echo 'Hi! This is PHP version ' . phpversion(); PI Data: echo 'Hi! This is PHP version ' . phpversion();

Page 84: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Consuming Yahoo XMLReader: Consuming Yahoo ShoppingShopping

<?xml version="1.0" encoding="ISO-8859-1"?><?xml version="1.0" encoding="ISO-8859-1"?><ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="urn:yahoo:prods" xmlns="urn:yahoo:prods" xsi:schemaLocation="urn:yahoo:prods xsi:schemaLocation="urn:yahoo:prods

http://api.shopping.yahoo.com/shoppingservice/v1/productsearch.xsd" http://api.shopping.yahoo.com/shoppingservice/v1/productsearch.xsd" totalResultsAvailable="8850" firstResultPosition="2" totalResultsReturned="2">totalResultsAvailable="8850" firstResultPosition="2" totalResultsReturned="2">

<<ResultResult>> <<CatalogCatalog ID="1991433722"> ID="1991433722"> <<UrlUrl ><![CDATA[http://shopping.yahoo.com/p:Linksys. . .2]]></Url>><![CDATA[http://shopping.yahoo.com/p:Linksys. . .2]]></Url> <<ProductNameProductName><![CDATA[Linksys WRT5. . .r Broadband ><![CDATA[Linksys WRT5. . .r Broadband

Router]]></ProductName>Router]]></ProductName> <<PriceFromPriceFrom>69.97</PriceFrom>>69.97</PriceFrom> <<PriceToPriceTo>89.99</PriceTo>>89.99</PriceTo> <Thumbnail /><!-- child elements Url (CDATA), Height, Width --><Thumbnail /><!-- child elements Url (CDATA), Height, Width --> <<DescriptionDescription><![CDATA[The Wireless-G . . .ces.]]></Description>><![CDATA[The Wireless-G . . .ces.]]></Description> <Summary><![CDATA[IEEE 802.3, ...]]></Summary><Summary><![CDATA[IEEE 802.3, ...]]></Summary> <UserRating /><!-- Rating sub elements --><UserRating /><!-- Rating sub elements --> <SpecificationList /><!-- 0+ Specification child elements --></SpecificationList><SpecificationList /><!-- 0+ Specification child elements --></SpecificationList> </Catalog></Catalog> </Result></Result></ResultSet></ResultSet>

Page 85: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Consuming Yahoo ShoppingXMLReader: Consuming Yahoo Shoppingxmlreader/rest_yahoo_shopping.phpxmlreader/rest_yahoo_shopping.php

function getTextValue($reader) { ... }function getTextValue($reader) { ... }function processCatalog($reader) { ... }function processCatalog($reader) { ... }function processResult($reader) { ... }function processResult($reader) { ... }

/* URL to Product Search service *//* URL to Product Search service */$url = 'http://api.shopping.yahoo.com/ShoppingService/V1/productSearch';$url = 'http://api.shopping.yahoo.com/ShoppingService/V1/productSearch';

/* The query is separate here as the terms must be encoded. *//* The query is separate here as the terms must be encoded. */$url .= '?query='.rawurlencode('linksys');$url .= '?query='.rawurlencode('linksys');

/* Complete the URL with App ID, limit to 1 result and start at second record *//* Complete the URL with App ID, limit to 1 result and start at second record */$url .= "&appid=zzz&results=2&start=2";$url .= "&appid=zzz&results=2&start=2";

$reader = new XMLReader();$reader = new XMLReader();

if (! $reader->open($url)) { print "Cannot access Webservice\n"; exit; }if (! $reader->open($url)) { print "Cannot access Webservice\n"; exit; }

while($reader->name != "Result") { $reader->read(); }while($reader->name != "Result") { $reader->read(); }do {do { processResult($reader);processResult($reader);} while($reader->next('Result'));} while($reader->next('Result'));

Page 86: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Consuming Yahoo ShoppingXMLReader: Consuming Yahoo Shoppingxmlreader/rest_yahoo_shopping.phpxmlreader/rest_yahoo_shopping.php

function getTextValue($reader) {function getTextValue($reader) { if ($reader->nodeType != if ($reader->nodeType != XMLReader::ELEMENTXMLReader::ELEMENT || $reader->isEmptyElement || $reader->isEmptyElement || ($reader->read() && $reader->nodeType == || ($reader->read() && $reader->nodeType == XMLReader::END_ELEMENTXMLReader::END_ELEMENT)))) return;return; $retVal = $reader->value;$retVal = $reader->value; $reader->read();$reader->read(); return $retVal;return $retVal;}}

function processResult($reader) {function processResult($reader) { $depth = $reader->depth;$depth = $reader->depth; if ($reader->isEmptyElement || ($reader->read() && if ($reader->isEmptyElement || ($reader->read() && $reader->nodeType == $reader->nodeType == XMLReader::END_ELEMENTXMLReader::END_ELEMENT)))) return;return;

while($depth < $reader->depth && $reader->name != "Catalog") { $reader->read(); while($depth < $reader->depth && $reader->name != "Catalog") { $reader->read(); };};processCatalog($reader);processCatalog($reader);/* Read until </Result> is encountered *//* Read until </Result> is encountered */while($depth < $reader->depth) { $reader->read(); }while($depth < $reader->depth) { $reader->read(); }

}}

Page 87: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Consuming Yahoo ShoppingXMLReader: Consuming Yahoo Shoppingxmlreader/rest_yahoo_shopping.phpxmlreader/rest_yahoo_shopping.php

function processCatalog($reader) {function processCatalog($reader) { $depth = $reader->depth;$depth = $reader->depth; print "Catalog ID".$reader->getAttribute('ID')."\n";print "Catalog ID".$reader->getAttribute('ID')."\n";

if ($reader->isEmptyElement || ($reader->read() && if ($reader->isEmptyElement || ($reader->read() && $reader->nodeType == $reader->nodeType == XMLReader::END_ELEMENTXMLReader::END_ELEMENT)))) return;return; while($depth < $reader->depth) {while($depth < $reader->depth) { switch ($reader->name) {switch ($reader->name) { case "ProductName":case "ProductName": case "PriceFrom":case "PriceFrom": case "PriceTo":case "PriceTo": case "Description":case "Description": case "Url":case "Url":

print $reader->name.": ".getTextValue($reader)."\n";print $reader->name.": ".getTextValue($reader)."\n"; }} $reader->next();$reader->next(); }}}}

Page 88: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Consuming Yahoo ShoppingXMLReader: Consuming Yahoo ShoppingRESULTS (Abbreviated)RESULTS (Abbreviated)

Catalog ID1990338714Catalog ID1990338714Url: Url:

http://shopping.yahoo.com/p:Linksys%20Instant%20Broadband%20Etherhttp://shopping.yahoo.com/p:Linksys%20Instant%20Broadband%20EtherFast%20Cable%2FDSL%20Router:1990338714Fast%20Cable%2FDSL%20Router:1990338714

ProductName: Linksys Instant Broadband EtherFast Cable/DSL RouterProductName: Linksys Instant Broadband EtherFast Cable/DSL RouterPriceFrom: 39.99PriceFrom: 39.99PriceTo: 72.71PriceTo: 72.71Description: <P>Linksys, a provider of networking hardware for the Description: <P>Linksys, a provider of networking hardware for the

small/medium business (SMB), small office/home office (SOHO), and small/medium business (SMB), small office/home office (SOHO), and enterprise markets and broadband networking hardware for the home, has enterprise markets and broadband networking hardware for the home, has announced the new EtherFast Cable/DSL Router. The first in the new announced the new EtherFast Cable/DSL Router. The first in the new Instant Broadband series, this Linksys broadband router will enable home Instant Broadband series, this Linksys broadband router will enable home or office users to connect their computers to a cable or DSL modem and or office users to connect their computers to a cable or DSL modem and securely share Internet access and perform networking tasks such as file securely share Internet access and perform networking tasks such as file and printer sharing. The built-in hardware firewall gives users the security and printer sharing. The built-in hardware firewall gives users the security of sharing files without fear of intruders hacking into the network. </P>of sharing files without fear of intruders hacking into the network. </P>

Page 89: Advanced XML with PHP 5 - CDATA Zone

XMLReader: DTD ValidationXMLReader: DTD Validationxmlreader/validation/reader.xmlxmlreader/validation/reader.xml

<!DOCTYPE chapter [<!DOCTYPE chapter [<!ELEMENT chapter (title, para, section)><!ELEMENT chapter (title, para, section)><!ELEMENT title (#PCDATA)><!ELEMENT title (#PCDATA)><!ELEMENT para ANY><!ELEMENT para ANY><!ATTLIST para name CDATA "default"><!ATTLIST para name CDATA "default"><!ELEMENT section (#PCDATA)><!ELEMENT section (#PCDATA)><!ATTLIST section id ID #REQUIRED><!ATTLIST section id ID #REQUIRED>]>]><chapter><chapter> <title>XMLReader</title><title>XMLReader</title> <para><para> First ParagraphFirst Paragraph </para></para> <section id="about"><section id="about"> <title>About this Document</title><title>About this Document</title> <para>content</para><para>content</para> </section></section></chapter></chapter>

Page 90: Advanced XML with PHP 5 - CDATA Zone

XMLReader: DTD ValidationXMLReader: DTD Validationxmlreader/validation/reader.phpxmlreader/validation/reader.php

$objReader = XMLReader::open('reader.xml');$objReader = XMLReader::open('reader.xml');$objReader->setParserProperty(XMLReader::VALIDATE, TRUE);$objReader->setParserProperty(XMLReader::VALIDATE, TRUE);

/* As of PHP 5.2 LIBXML Parser Options may be passed *//* As of PHP 5.2 LIBXML Parser Options may be passed */// $objReader = XMLReader::open('reader.xml', NULL,// $objReader = XMLReader::open('reader.xml', NULL, LIBXML_DTDVALID);LIBXML_DTDVALID);

libxml_use_internal_errors(TRUE);libxml_use_internal_errors(TRUE);

while ($objReader->read()) {while ($objReader->read()) { if (if ( ! $objReader->isValid()! $objReader->isValid()) {) { print "NOT VALID\n";print "NOT VALID\n"; break;break; }}}}

$arErrors = libxml_get_errors();$arErrors = libxml_get_errors();foreach ($arErrors AS $xmlError) {foreach ($arErrors AS $xmlError) { print $xmlError->message;print $xmlError->message;}}

Page 91: Advanced XML with PHP 5 - CDATA Zone

XMLReader: DTD ValidationXMLReader: DTD ValidationRESULTSRESULTS

PHP Strict Standards: Non-static method XMLReader::open() should not be PHP Strict Standards: Non-static method XMLReader::open() should not be called statically in /home/rrichards/workshop/xmlreader/validation/reader.php called statically in /home/rrichards/workshop/xmlreader/validation/reader.php on line 2on line 2

NOT VALIDNOT VALIDElement section was declared #PCDATA but contains non Element section was declared #PCDATA but contains non text nodestext nodes

Page 92: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Relax NG ValidationXMLReader: Relax NG Validationxmlreader/validation/reader.rngxmlreader/validation/reader.rng

<?xml version="1.0" encoding="utf-8" ?><?xml version="1.0" encoding="utf-8" ?><element name="chapter" <element name="chapter" xmlns="http://relaxng.org/ns/structure/1.0">xmlns="http://relaxng.org/ns/structure/1.0"> <element name="title"><element name="title"> <text/><text/> </element></element> <element name="para"><element name="para"> <text/><text/> </element></element> <element name="section"><element name="section"> <attribute name="id" /><attribute name="id" /> <text/><text/> </element></element></element></element>

Page 93: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Relax NG ValidationXMLReader: Relax NG Validationxmlreader/validation/reader-rng.phpxmlreader/validation/reader-rng.php

$objReader = XMLReader::open('reader.xml');$objReader = XMLReader::open('reader.xml');$objReader->setRelaxNGSchema('reader.rng');$objReader->setRelaxNGSchema('reader.rng');

libxml_use_internal_errors(TRUE);libxml_use_internal_errors(TRUE);

while ($objReader->read()) {while ($objReader->read()) { if (if ( ! $objReader->isValid()! $objReader->isValid()) {) { print "NOT VALID\n";print "NOT VALID\n"; break;break; }}}}

$arErrors = libxml_get_errors();$arErrors = libxml_get_errors();foreach ($arErrors AS $xmlError) {foreach ($arErrors AS $xmlError) { print $xmlError->message;print $xmlError->message;}}

Page 94: Advanced XML with PHP 5 - CDATA Zone

XMLReader: Relax NG ValidationXMLReader: Relax NG Validation RESULTSRESULTS

PHP Strict Standards: Non-static method XMLReader::open() should not be PHP Strict Standards: Non-static method XMLReader::open() should not be called statically in /home/rrichards/workshop/xmlreader/validation/reader.php called statically in /home/rrichards/workshop/xmlreader/validation/reader.php on line 2on line 2

NOT VALIDNOT VALIDDid not expect element title thereDid not expect element title there

Page 95: Advanced XML with PHP 5 - CDATA Zone

XMLReader: XML Schema ValidationXMLReader: XML Schema Validationxmlreader/validation/reader.xsdxmlreader/validation/reader.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="chapter"><xsd:element name="chapter"> <xsd:complexType><xsd:complexType> <xsd:sequence><xsd:sequence> <xsd:element name="title" type="xsd:string"/><xsd:element name="title" type="xsd:string"/> <xsd:element name="para" type="xsd:string"/><xsd:element name="para" type="xsd:string"/> <xsd:element name="section"><xsd:element name="section"> <xsd:complexType><xsd:complexType> <xsd:simpleContent><xsd:simpleContent> <xsd:extension base="xsd:string"><xsd:extension base="xsd:string"> <xsd:attribute name="id" type="xsd:ID"/><xsd:attribute name="id" type="xsd:ID"/> </xsd:extension></xsd:extension> </xsd:simpleContent></xsd:simpleContent> </xsd:complexType></xsd:complexType> </xsd:element></xsd:element> </xsd:sequence></xsd:sequence> </xsd:complexType></xsd:complexType> </xsd:element></xsd:element></xsd:schema></xsd:schema>

Page 96: Advanced XML with PHP 5 - CDATA Zone

XMLReader: XML Schema ValidationXMLReader: XML Schema Validationxmlreader/validation/reader-xsd.phpxmlreader/validation/reader-xsd.php

$objReader = XMLReader::open('reader.xml');$objReader = XMLReader::open('reader.xml');$objReader->setSchema('reader.xsd');$objReader->setSchema('reader.xsd');

libxml_use_internal_errors(TRUE);libxml_use_internal_errors(TRUE);

while ($objReader->read()) {while ($objReader->read()) { if (if ( ! $objReader->isValid()! $objReader->isValid()) {) { print "NOT VALID\n";print "NOT VALID\n"; break;break; }}}}

$arErrors = libxml_get_errors();$arErrors = libxml_get_errors();foreach ($arErrors AS $xmlError) {foreach ($arErrors AS $xmlError) { print $xmlError->message;print $xmlError->message;}}

LIBXML2-2.20+ REQUIREDLIBXML2-2.20+ REQUIRED

Page 97: Advanced XML with PHP 5 - CDATA Zone

XMLReader: XML Schema ValidationXMLReader: XML Schema Validation RESULTSRESULTS

PHP Strict Standards: Non-static method XMLReader::open() should not be PHP Strict Standards: Non-static method XMLReader::open() should not be called statically in /home/rrichards/workshop/xmlreader/validation/reader.php called statically in /home/rrichards/workshop/xmlreader/validation/reader.php on line 2on line 2

NOT VALIDNOT VALIDElement 'para', attribute 'name': The attribute 'name' is not Element 'para', attribute 'name': The attribute 'name' is not allowed.allowed.Element 'section': Element content is not allowed, because Element 'section': Element content is not allowed, because the content type is a simple type definition.the content type is a simple type definition.

Page 98: Advanced XML with PHP 5 - CDATA Zone

Tree ParsersTree Parsers

� Pros:Pros:� Full navigation and modification of the XML Full navigation and modification of the XML

documentdocument� Navigating and searching are extremely fast once Navigating and searching are extremely fast once

the tree is loaded into memorythe tree is loaded into memory

� Cons:Cons:� Must wait until entire tree is loaded to begin Must wait until entire tree is loaded to begin

working with the XML.working with the XML.� Memory intensiveMemory intensive

Page 99: Advanced XML with PHP 5 - CDATA Zone

Streaming ParsersStreaming Parsers

� Pros:Pros:� Uses minimal memoryUses minimal memory� Processing takes place immediately while the Processing takes place immediately while the

document is parseddocument is parsed

� Cons:Cons:� Minimal to no navigation support (forward only)Minimal to no navigation support (forward only)� No document editing capabilitiesNo document editing capabilities

Page 100: Advanced XML with PHP 5 - CDATA Zone

Raw Test DataRaw Test Data<books><books> <book id="1"><title>1</title><pages>1</pages></book><book id="1"><title>1</title><pages>1</pages></book> <book id="2"><title>2</title><pages>2</pages></book><book id="2"><title>2</title><pages>2</pages></book> <!-- Remaining book elements for a total of 200,000 --><!-- Remaining book elements for a total of 200,000 --></books></books>

Memory Usage:Memory Usage:

177KB26KB85.6MB85.6MB

XMLReaderext/xmlSimpleXMLDOM

0.2380.9306.5836.623

XMLReaderext/xmlSimpleXMLDOM

Using every optimization possible the following results show the time in seconds to locate the book element having id="5000".

Average Time in Seconds for Optimized Search for an Element:

Page 101: Advanced XML with PHP 5 - CDATA Zone

XMLWriterXMLWriter

� Lightweight and forward-only API for Lightweight and forward-only API for generating well formed XMLgenerating well formed XML

� Automatically escapes dataAutomatically escapes data� Works with PHP 4.3+ available at Works with PHP 4.3+ available at

http://pecl.php.net/package/xmlwriterhttp://pecl.php.net/package/xmlwriter� Object Oriented API available for PHP 5+Object Oriented API available for PHP 5+� Part of core PHP distribution since PHP 5.1.2Part of core PHP distribution since PHP 5.1.2

Page 102: Advanced XML with PHP 5 - CDATA Zone

XMLWriter: Simple ExampleXMLWriter: Simple Examplexmlwriter/simple.phpxmlwriter/simple.php

<?php<?php$xw = new XMLWriter();$xw = new XMLWriter();$xw->openMemory();$xw->openMemory();

/* Turn on indenting to make output look pretty and set string /* Turn on indenting to make output look pretty and set string used for indenting as teh default space is too short*/used for indenting as teh default space is too short*/$xw->setIndent(TRUE);$xw->setIndent(TRUE);$xw->setIndentString(' ');$xw->setIndentString(' ');

/* Write out the optional XML declaration only specifying version *//* Write out the optional XML declaration only specifying version */$xw->startDocument('1.0');$xw->startDocument('1.0');

/* Create the opening document element, which is namespaced *//* Create the opening document element, which is namespaced */$xw->startElementNs(NULL, "chapter", "http://www.example.com/default");$xw->startElementNs(NULL, "chapter", "http://www.example.com/default");

/* Write out an xml namespace declaration that is used later in the document *//* Write out an xml namespace declaration that is used later in the document */$res = $xw->writeAttribute('xmlns:a', 'http://www.example.com/namespace-a');$res = $xw->writeAttribute('xmlns:a', 'http://www.example.com/namespace-a');

/* Write complete elements with text content *//* Write complete elements with text content */$xw->writeElement('a:title', 'XMLReader');$xw->writeElement('a:title', 'XMLReader');$xw->writeElement('para', 'spec chars < > & " inside para element');$xw->writeElement('para', 'spec chars < > & " inside para element');

Page 103: Advanced XML with PHP 5 - CDATA Zone

XMLWriter: Simple ExampleXMLWriter: Simple Examplexmlwriter/simple.phpxmlwriter/simple.php

/* start an element and add an attribute to it *//* start an element and add an attribute to it */$xw->startElement('a:section');$xw->startElement('a:section');$xw->writeAttribute('a:id', 'about');$xw->writeAttribute('a:id', 'about');

/* Write out an element with special characters *//* Write out an element with special characters */$xw->writeElement('title', 'Pro PHP XML & Webservices');$xw->writeElement('title', 'Pro PHP XML & Webservices');

$xw->startElement('para'); /* This opens the para element */$xw->startElement('para'); /* This opens the para element */

$xw->writeComment("this is a comment");$xw->writeComment("this is a comment");$xw->text(" ");$xw->text(" ");$xw->writePi("php", "echo 'Hi! This is PHP version ' . phpversion(); ");$xw->writePi("php", "echo 'Hi! This is PHP version ' . phpversion(); ");$xw->text("\n ");$xw->text("\n ");

$xw->endElement(); /* This will close the open para element */$xw->endElement(); /* This will close the open para element */

$xw->endDocument();$xw->endDocument();

/* Flush and clear the buffer *//* Flush and clear the buffer */echo $xw->flush(true);echo $xw->flush(true);?>?>

Page 104: Advanced XML with PHP 5 - CDATA Zone

XMLWriter: Simple ExampleXMLWriter: Simple Examplexmlwriter/simple.phpxmlwriter/simple.php

/* start an element and add an attribute to it *//* start an element and add an attribute to it */$xw->startElement('a:section');$xw->startElement('a:section');$xw->writeAttribute('a:id', 'about');$xw->writeAttribute('a:id', 'about');

/* Write out an element with special characters *//* Write out an element with special characters */$xw->writeElement('title', 'Pro PHP XML & Webservices');$xw->writeElement('title', 'Pro PHP XML & Webservices');

$xw->startElement('para'); /* This opens the para element */$xw->startElement('para'); /* This opens the para element */

$xw->writeComment("this is a comment");$xw->writeComment("this is a comment");$xw->text(" ");$xw->text(" ");$xw->writePi("php", "echo 'Hi! This is PHP version ' . phpversion(); ");$xw->writePi("php", "echo 'Hi! This is PHP version ' . phpversion(); ");$xw->text("\n ");$xw->text("\n ");

$xw->endElement(); /* This will close the open para element */$xw->endElement(); /* This will close the open para element */

$xw->endDocument();$xw->endDocument();

/* Flush and clear the buffer *//* Flush and clear the buffer */echo $xw->flush(true);echo $xw->flush(true);?>?>

Page 105: Advanced XML with PHP 5 - CDATA Zone

XMLWriter: Simple ExampleXMLWriter: Simple ExampleResultsResults

<?xml version="1.0"?><?xml version="1.0"?><chapter xmlns="http://www.example.com/default"<chapter xmlns="http://www.example.com/default" xmlns:a="http://www.example.com/namespace-a">xmlns:a="http://www.example.com/namespace-a"> <a:title>XMLReader</a:title><a:title>XMLReader</a:title> <para>spec chars &lt; &gt; &amp; &quot; inside para <para>spec chars &lt; &gt; &amp; &quot; inside para element</para>element</para> <a:section a:id="about"><a:section a:id="about"> <title>Pro PHP XML &amp; Webservices</title><title>Pro PHP XML &amp; Webservices</title> <para><para> <!--this is a comment--><!--this is a comment--> <?php echo 'Hi! This is PHP version ' . phpversion(); ?><?php echo 'Hi! This is PHP version ' . phpversion(); ?> </para></para> </a:section></a:section></chapter></chapter>

Page 106: Advanced XML with PHP 5 - CDATA Zone

XSLXSL� Used to transform XML dataUsed to transform XML data� XSLT based on XPathXSLT based on XPath� Works with DOM and SimpleXML, although the Works with DOM and SimpleXML, although the

DOM extension is required.DOM extension is required.� Provides the capability of calling PHP functions Provides the capability of calling PHP functions

during a transformationduring a transformation� DOM nodes may be returned from PHP functionsDOM nodes may be returned from PHP functions� The LIBXML_NOCDATA and LIBXML_NOENT The LIBXML_NOCDATA and LIBXML_NOENT

constants are your friends.constants are your friends.� libxslt 1.1.5+ is recommended to avoid problems libxslt 1.1.5+ is recommended to avoid problems

when using xsl:keywhen using xsl:key

Page 107: Advanced XML with PHP 5 - CDATA Zone

XSL: XML Input Data XSL: XML Input Data xsl/sites.xmlxsl/sites.xml

<?xml version="1.0"?><?xml version="1.0"?><sites><sites> <site xml:id="php-gen"><site xml:id="php-gen"> <name>PHP General</name><name>PHP General</name> <url>http://news.php.net/group.php?group=php.general&amp;format=rss</url><url>http://news.php.net/group.php?group=php.general&amp;format=rss</url> </site></site> <site xml:id="php-pear"><site xml:id="php-pear"> <name>PHP Pear Dev</name><name>PHP Pear Dev</name> <url>http://news.php.net/group.php?group=php.pear.dev&amp;format=rss</url><url>http://news.php.net/group.php?group=php.pear.dev&amp;format=rss</url> </site></site> <site xml:id="php-planet"><site xml:id="php-planet"> <name>Planet PHP</name><name>Planet PHP</name> <url>http://www.planet-php.org/rss/</url><url>http://www.planet-php.org/rss/</url> </site></site></sites></sites>

Page 108: Advanced XML with PHP 5 - CDATA Zone

XSL: Simple TransformationXSL: Simple Transformationxsl/simple_stylesheet.xslxsl/simple_stylesheet.xsl

<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <html> <body> <xsl:apply-templates select="/sites/site"/> </body> </html> </xsl:template>

<xsl:template match="/sites/site"> <p><xsl:value-of select="./name"/> : <xsl:value-of select="./url" disable-output-escaping="yes"/></p> </xsl:template></xsl:stylesheet>

Page 109: Advanced XML with PHP 5 - CDATA Zone

XSL: Simple TransformationXSL: Simple Transformationxsl/simple_stylesheet.phpxsl/simple_stylesheet.php

/* Load Stylesheet */$stylesheet = new DOMDocument();$stylesheet->load('simple_stylesheet.xsl');

/* Create XSL Processor */$proc = new xsltprocessor();$proc->importStylesheet($stylesheet);

/* Load XML Data */$dom = new DOMDocument();$dom->load('sites.xml');

print $proc->transformToXML($dom);

Page 110: Advanced XML with PHP 5 - CDATA Zone

XSL: Simple TransformationXSL: Simple TransformationRESULTSRESULTS

<html> <body> <p>PHP General : http://news.php.net/group.php?group=php.general&format=rss</p> <p>PHP Pear Dev : http://news.php.net/group.php?group=php.pear.dev&format=rss</p> <p>Planet PHP : http://www.planet-php.org/rss/</p> </body></html>

Page 111: Advanced XML with PHP 5 - CDATA Zone

XSL: Advanced TransformationXSL: Advanced Transformationxsl/advanced_stylesheet.phpxsl/advanced_stylesheet.php

function initReader($url) { $GLOBALS['reader'] = new XMLReader(); if ($GLOBALS['reader']->open($url)) { while ($GLOBALS['reader']->read() && $GLOBALS['reader']->name != 'item') { }

if ($GLOBALS['reader']->name == 'item') return 1; } $GLOBALS['reader'] = NULL; return 0;}

function readNextItem() { if ($GLOBALS['reader'] == NULL) return NULL; if ($GLOBALS['beingProc']) $GLOBALS['reader']->next('item'); else $GLOBALS['beingProc'] = TRUE; if ($GLOBALS['reader']->name == 'item') return $GLOBALS['reader']->expand(); return NULL;}

Page 112: Advanced XML with PHP 5 - CDATA Zone

XSL: Advanced TransformationXSL: Advanced Transformationxsl/advanced_stylesheet.phpxsl/advanced_stylesheet.php

$beingProc = FALSE;$reader = NULL;

/* Load Stylesheet */$stylesheet = new DOMDocument();$stylesheet->load('advanced_stylesheet.xsl');

/* Create XSL Processor */$proc = new xsltprocessor();$proc->importStylesheet($stylesheet);

/* Load XML Data */$dom = new DOMDocument();$dom->load('sites.xml');

$proc->setParameter(NULL, 'siteid', 'php-gen');$proc->registerPHPFunctions('initReader');$proc->registerPHPFunctions('readNextItem');print $proc->transformToXML($dom);/* END */

Page 113: Advanced XML with PHP 5 - CDATA Zone

XSL: Advanced TransformationXSL: Advanced Transformationxsl/advanced_stylesheet.xslxsl/advanced_stylesheet.xsl

<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" version="1.0"> <xsl:output method="html"/> <xsl:param name="siteid" select="0" />

<xsl:template match="/"> <html><body> <xsl:apply-templates select="id($siteid)"/> </body></html> </xsl:template>

<xsl:template match="/sites/site"> <xsl:variable name="itemnum" select="php:functionString('initReader', ./url)" /> <xsl:if test="number($itemnum) > 0"> <xsl:call-template name="itemproc" /> </xsl:if> </xsl:template>

Page 114: Advanced XML with PHP 5 - CDATA Zone

XSL: Advanced TransformationXSL: Advanced Transformationxsl/advanced_stylesheet.xslxsl/advanced_stylesheet.xsl

<xsl:template match="item"> <p> Title: <b><xsl:value-of select="./title" /></b><br/><br/> URL: <xsl:value-of select="./link" /><br/> Published: <xsl:value-of select="./pubDate" /><br/> </p> </xsl:template>

<xsl:template name="itemproc"> <xsl:variable name="nodeset" select="php:functionString('readNextItem')" /> <xsl:if test="boolean($nodeset)"> <xsl:apply-templates select="$nodeset"/> <xsl:call-template name="itemproc" /> </xsl:if> </xsl:template>

</xsl:stylesheet>

Page 115: Advanced XML with PHP 5 - CDATA Zone

XSL: Advanced TransformationXSL: Advanced TransformationResults viewed through a browserResults viewed through a browser

xsl/advanced_stylesheet.htmlxsl/advanced_stylesheet.html

Title: Re: Spreadsheet Writer

URL: http://news.php.net/php.general/241446Published: Thu, 07 Sep 2006 13:52:09 –0400

Title: Re: Spreadsheet Writer

URL: http://news.php.net/php.general/241447Published: Thu, 07 Sep 2006 13:52:09 -0400

Title: Re: Spreadsheet Writer

URL: http://news.php.net/php.general/241448Published: Thu, 07 Sep 2006 13:52:09 -0400

Page 116: Advanced XML with PHP 5 - CDATA Zone

Questions?Questions?

http://www.cdatazone.org/talks/quebec_2007/workshop.zip

[email protected]