Advanced XML Advanced XML with PHP 5 with PHP 5 March 14, 2007 - - PowerPoint PPT Presentation

advanced xml advanced xml with php 5 with php 5
SMART_READER_LITE
LIVE PREVIEW

Advanced XML Advanced XML with PHP 5 with PHP 5 March 14, 2007 - - PowerPoint PPT Presentation

Advanced XML Advanced XML with PHP 5 with PHP 5 March 14, 2007 March 14, 2007 Robert Richards Robert Richards rrichards@ctindustries.net rrichards@ctindustries.net http://www.cdatazone.org/talks/quebec_2007/workshop.zip


slide-1
SLIDE 1

Advanced XML Advanced XML with PHP 5 with PHP 5

March 14, 2007 March 14, 2007 Robert Richards Robert Richards rrichards@ctindustries.net rrichards@ctindustries.net

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

slide-2
SLIDE 2

Agenda Agenda

Introduction to Terms and Concepts

Introduction to Terms and Concepts

Libxml

Libxml

SimpleXML

SimpleXML

SDO

SDO

DOM

DOM

XMLReader

XMLReader

XMLWriter

XMLWriter

XSL

XSL

slide-3
SLIDE 3

XML Namespaces XML 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/rob http://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.

slide-4
SLIDE 4

XML Namespace Example XML 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>

slide-5
SLIDE 5

XML Namespace Example XML 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>

slide-6
SLIDE 6

Illegal Namespace Usage Illegal 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"

  • rder:type="legal"
  • rder: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!

slide-7
SLIDE 7

Illegal Namespace Usage Illegal 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"

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

</ship:shipping> </ship:shipping> </order> </order> <!-- attributes on shipping element are valid ! --> <!-- attributes on shipping element are valid ! -->

slide-8
SLIDE 8

Reserved Namespaces and Reserved Namespaces and Prefixes Prefixes

The prefix

The prefix xml xml is bound to is bound to http://www.w3.org/XML/1998/namespace http://www.w3.org/XML/1998/namespace. .

The prefix

The prefix xmlns xmlns 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 xml xml. .

slide-9
SLIDE 9

Schemas and Validation Schemas 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 Schema

XML Schema

RelaxNG

RelaxNG

slide-10
SLIDE 10

Document Type Definition Document Type Definition (DTD)

(DTD)

validation/courses-dtd.xml validation/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>

slide-11
SLIDE 11

DTD and IDs DTD and IDs

validation/course-id.xml validation/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>

slide-12
SLIDE 12

XML Schema XML Schema

validation/course.xsd validation/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>

slide-13
SLIDE 13

RelaxNG RelaxNG

validation/course.rng validation/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>

slide-14
SLIDE 14

XPath XPath

Language to locate and retrieve information

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

A foundation for XSLT

A foundation for XSLT

An XML document is a tree containing nodes

An XML document is a tree containing nodes

The XML document is the root node

The XML document is the root node

Locations are addressable similar to the syntax

Locations are addressable similar to the syntax for a filesystem for a filesystem

slide-15
SLIDE 15

XPath Reference Document XPath Reference Document

xpath/courses.xml xpath/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>

slide-16
SLIDE 16

XPath Location Example XPath Location Example

xpath/location.php xpath/location.php /courses/course/description /courses/*/description //description //description[ancestor::course]

Expression: Resulting Nodset:

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

slide-17
SLIDE 17

XPath Function Example XPath Function Example

xpath/function.php xpath/function.php

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

French II French II Intermediate French Intermediate French content content

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>

slide-18
SLIDE 18

XPath and Namespaces XPath and Namespaces

xpath/namespaces.php xpath/namespaces.php //title Empty NodeSet //defns Empty 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:

slide-19
SLIDE 19

PHP and XML PHP and XML

PHP 5 introduced numerous interfaces for

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

The libxml2 library (http://www.xmlsoft.org/)

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

The sister library libxslt provides XSLT support

The sister library libxslt provides XSLT support

I/O is handled via PHP streams

I/O is handled via PHP streams

ext/domxml was removed in favor of ext/dom

ext/domxml was removed in favor of ext/dom

slide-20
SLIDE 20

XML Entensions for PHP 5 XML Entensions for PHP 5

ext/libxml

ext/libxml

ext/xml (SAX push parser)

ext/xml (SAX push parser)

ext/dom

ext/dom

ext/simplexml

ext/simplexml

ext/xmlreader (pull parser)

ext/xmlreader (pull parser)

pecl/sdo (SCA_SDO)

pecl/sdo (SCA_SDO)

ext/xmlwriter

ext/xmlwriter

ext/xsl

ext/xsl

ext/wddx

ext/wddx

ext/soap

ext/soap

slide-21
SLIDE 21

Libxml Libxml

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.

slide-22
SLIDE 22

Libxml: Parser Options Libxml: Parser Options

Disable network access when loading

LIBXML_NONET

Merge CDATA nodes in Text nodes

LIBXML_NOCDATA

Perform XIncludes during parsing

LIBXML_XINCLUDE

Remove insignificant whitespace on parsing

LIBXML_NOBLANKS

Suppress parser warnings from libxml2

LIBXML_NOWARNING

Suppress parsing errors from libxml2

LIBXML_NOERROR

Loads subsets and perform validation

LIBXML_DTDVALID

Create defaulted attributes defined in DTD

LIBXML_DTDATTR

Load subsets but do not perform validation

LIBXML_DTDLOAD

Substitute entities with replacement content

LIBXML_NOENT

slide-23
SLIDE 23

Libxml: Error Handling Libxml: 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 )

slide-24
SLIDE 24

Libxml: LibXMLError Libxml: LibXMLError

Class: LibXMLError

Properties (Read-Only): (int) level (int) code (int) column (string) message (string) file (int) line

LibXMLError::code Values:

LIBXML_ERR_NONE LIBXML_ERR_WARNING LIBXML_ERR_ERROR LIBXML_ERR_FATAL

slide-25
SLIDE 25

LibXMLError Example LibXMLError Example

libxml/error.php libxml/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"; } ?>

slide-26
SLIDE 26

LibXMLError Result LibXMLError 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 4 in 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 4 Entity, line: 1 in /home/rrichards/workshop/libxml/error.php on line 4

New Error Handling: New Error Handling:

  • bject(LibXMLError)#2 (6) {
  • bject(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) } }

slide-27
SLIDE 27

Libxml: Stream Context Libxml: 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');

slide-28
SLIDE 28

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

XML extensions are unicode ready for PHP 6

XML extensions are unicode ready for PHP 6

Both the UTF-8 binary strings (existing behavior)

Both the UTF-8 binary strings (existing behavior) AND AND 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 String String based XML documents based XML documents

Insures original encoding is not lost

Insures original encoding is not lost

Does not affect usage with unicode disabled

Does not affect usage with unicode disabled

slide-29
SLIDE 29

Forward Compatibility Forward 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 = b b'<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());

slide-30
SLIDE 30

SimpleXML SimpleXML

Provides simple access to XML documents

Provides simple access to XML documents

Operates only on elements and attributes

Operates only on elements and attributes

Contains XPath support

Contains XPath support

Allows for modifications to the XML

Allows for modifications to the XML

Zero copy interoperability with DOM

Zero copy interoperability with DOM

Examples for PHP 5.1.6+

Examples for PHP 5.1.6+

New in PHP 5.1.3

New 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().

slide-31
SLIDE 31

SimpleXML: Consuming Yahoo WebSearch SimpleXML: Consuming Yahoo WebSearch

simplexml/yahoo_websearch_results.xml simplexml/yahoo_websearch_results.xml

<ResultSet <ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

totalResultsReturned totalResultsReturned="3" firstResultPosition="1"> ="3" firstResultPosition="1"> < <Result Result> > < <Title Title>Zend Technologies - PHP 5 . . .</Title> >Zend Technologies - PHP 5 . . .</Title> <Summary>titletext = $dom-&amp;gt;createText. . .</Summary> <Summary>titletext = $dom-&amp;gt;createText. . .</Summary> < <Url Url>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> < <ModificationDate ModificationDate>1171872000</ModificationDate> >1171872000</ModificationDate> <MimeType>text/html</MimeType> <MimeType>text/html</MimeType> <!-- Abbreviated Content --> <!-- Abbreviated Content --> </Result> </Result> <!-- Abbreviated Response --> <!-- Abbreviated Response --> </ResultSet> </ResultSet>

slide-32
SLIDE 32

SimpleXML: Consuming Yahoo WebSearch SimpleXML: Consuming Yahoo WebSearch

simplexml/yahoo_search.php simplexml/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"; } } } }

slide-33
SLIDE 33

SimpleXML: Consuming Yahoo WebSearch SimpleXML: Consuming Yahoo WebSearch

RESULTS RESULTS

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.php Url: http://www.zend.com/php5/articles/php5-xmlphp.php Mod Date: Feb 19 2007 Mod 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/1713 Url: http://devzone.zend.com/node/view/id/1713 Mod Date: Feb 26 2007 Mod Date: Feb 26 2007 Title: FreshPorts -- textproc/php5-xml Title: FreshPorts -- textproc/php5-xml Url: http://www.freshports.org/textproc/php5-xml Url: http://www.freshports.org/textproc/php5-xml Mod Date: Feb 15 2007 Mod Date: Feb 15 2007

slide-34
SLIDE 34

SimpleXML: Namespaces SimpleXML: Namespaces

simplexml/sxe_ns_books.php simplexml/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->name

name)

) print $book->name; print $book->name;

} }

slide-35
SLIDE 35

SimpleXML: Namespaces SimpleXML: Namespaces Results Results

To Kill a Mockingbird To Kill a Mockingbird Question: Question: What happened to the other book title? What happened to the other book title?

slide-36
SLIDE 36

SimpleXML: Namespaces SimpleXML: Namespaces

simplexml/sxe_ns_books_prefix.php simplexml/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"; } }

slide-37
SLIDE 37

SimpleXML: Namespaces SimpleXML: Namespaces Results Results

Grapes of Wrath Grapes of Wrath Only book elements within the specified Only book elements within the specified namespace are used in the results namespace are used in the results

slide-38
SLIDE 38

SimpleXML: Xpath SimpleXML: Xpath

simplexml/sxe_xpath_ns.php simplexml/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.xml sxe_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";

slide-39
SLIDE 39

SimpleXML: XPath Results SimpleXML: XPath Results

Book Title: Book Title: Book Title: Book Title: Grapes of Wrath Grapes of Wrath Why doesn't the title " Why doesn't the title "To Kill a Mockingbird" To Kill a Mockingbird" get printed? get printed?

slide-40
SLIDE 40

SimpleXML: Xpath SimpleXML: Xpath

simplexml/sxe_xpath_ns_def.php simplexml/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.xml sxe_ns_books.xml'); '); $sxe->registerXPathNamespace("ec", " $sxe->registerXPathNamespace("ec", "http://www.example.com/ExteralClassics

http://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 Mockingbird Book Title: To Kill a Mockingbird

slide-41
SLIDE 41

SimpleXML: XPath Context SimpleXML: XPath Context

simplexml/sxe_xpath_context.php simplexml/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"; RESULTS RESULTS Book Price: $ Book Price: $

slide-42
SLIDE 42

SimpleXML: XPath Context SimpleXML: XPath Context

simplexml/sxe_xpath_ns_context.php simplexml/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"; RESULTS RESULTS Book Price: $10.99 Book Price: $10.99

slide-43
SLIDE 43

SimpleXML: Write some data SimpleXML: 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>

slide-44
SLIDE 44

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>

slide-45
SLIDE 45

SimpleXML: Advanced Editing SimpleXML: Advanced Editing

simplexml/editing.php simplexml/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();

slide-46
SLIDE 46

SimpleXML: Advanced Editing SimpleXML: Advanced Editing Results Results

<?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>

slide-47
SLIDE 47

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

simplexml/editing_php513.php simplexml/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->addChild addChild('result'); ('result'); $result-> $result->addChild addChild('title', $result_item['title']); ('title', $result_item['title']); $result-> $result->addChild addChild('description'); ('description'); $result->description = $result_item['descript']; $result->description = $result_item['descript']; } } print $rest->asXML(); print $rest->asXML();

slide-48
SLIDE 48

SimpleXML: Removing data SimpleXML: Removing data

remove_data.php remove_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(); ?> ?>

slide-49
SLIDE 49

SimpleXML: Removing data SimpleXML: Removing data

RESULTS RESULTS <?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>

slide-50
SLIDE 50

SDO (SDO_DAS_XML) SDO (SDO_DAS_XML)

Provides simple access to XML documents

Provides simple access to XML documents

Works in a similar fashion to SimpleXML

Works in a similar fashion to SimpleXML

Operates only on elements and attributes

Operates only on elements and attributes

Contains XPath support

Contains XPath support

Allows for modifications to the XML

Allows for modifications to the XML

Requires XML Schema

Requires XML Schema

Stricter than SimpleXML

Stricter than SimpleXML

Maps XML to Data Types

Maps XML to Data Types

slide-51
SLIDE 51

SDO: Consuming Yahoo ContextSearch SDO: Consuming Yahoo ContextSearch

sdo/yahoo_search_results.xml sdo/yahoo_search_results.xml

<ResultSet <ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

totalResultsReturned totalResultsReturned="3" firstResultPosition="1"> ="3" firstResultPosition="1"> < <Result Result> > < <Title Title>Zend Technologies - PHP 5 . . .</Title> >Zend Technologies - PHP 5 . . .</Title> <Summary>titletext = $dom-&amp;gt;createText. . .</Summary> <Summary>titletext = $dom-&amp;gt;createText. . .</Summary> < <Url Url>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> < <ModificationDate ModificationDate>1171872000</ModificationDate> >1171872000</ModificationDate> <MimeType>text/html</MimeType> <MimeType>text/html</MimeType> <!-- Abbreviated Content --> <!-- Abbreviated Content --> </Result> </Result> <!-- Abbreviated Response --> <!-- Abbreviated Response --> </ResultSet> </ResultSet>

slide-52
SLIDE 52

SDO: Consuming Yahoo ContextSearch SDO: Consuming Yahoo ContextSearch

sdo sdo/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";

} } } }

slide-53
SLIDE 53

SDO: Consuming Yahoo ContextSearch SDO: Consuming Yahoo ContextSearch

sdo sdo/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";

} } } }

slide-54
SLIDE 54

SDO: Consuming Yahoo ContextSearch SDO: Consuming Yahoo ContextSearch

RESULTS RESULTS

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.php Url: http://www.zend.com/php5/articles/php5-xmlphp.php Mod Date: Feb 19 2007 Mod 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/1713 Url: http://devzone.zend.com/node/view/id/1713 Mod Date: Feb 26 2007 Mod Date: Feb 26 2007 Title: Parsing XML using PHP5 Title: Parsing XML using PHP5 Url: http://www.developertutorials.com/tutorials/php/parsing-xml-using- Url: http://www.developertutorials.com/tutorials/php/parsing-xml-using- php5-050816/page1.html php5-050816/page1.html Mod Date: Feb 02 2007 Mod Date: Feb 02 2007

slide-55
SLIDE 55

SDO: XML Editing SDO: XML Editing

sdo/address.xsd sdo/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>

slide-56
SLIDE 56

SDO: XML Editing SDO: XML Editing

sdo/editing.php sdo/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>

slide-57
SLIDE 57

SDO: XML Editing SDO: XML Editing

sdo/editing_error.php sdo/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("address address"); "); $address = $xdoc->getRootDataObject(); $address = $xdoc->getRootDataObject(); $address->city = "Portland"; $address->city = "Portland"; $address-> $address->company company = "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:company Error: Cannot find property:company

slide-58
SLIDE 58

DOM DOM

Tree based parser

Tree based parser

Allows for creation and editing of XML documents

Allows for creation and editing of XML documents

W3C Specification with DOM Level 2/3 compliancy

W3C Specification with DOM Level 2/3 compliancy

Provides XPath support

Provides XPath support

Provides XInclude Support

Provides XInclude Support

Ability to work with HTML documents

Ability to work with HTML documents

Zero copy interoperability with SimpleXML

Zero copy interoperability with SimpleXML

Replacement for ext/domxml from PHP 4

Replacement for ext/domxml from PHP 4

slide-59
SLIDE 59

DOMNode Classes DOMNode Classes

DOMDocument

DOMDocument

DOMElement

DOMElement

DOMAttr

DOMAttr

DOMComment

DOMComment

DOMDocumentType

DOMDocumentType

DOMNotation

DOMNotation

DOMEntity

DOMEntity

DOMEntityReference

DOMEntityReference

DOMProcessingInstruction

DOMProcessingInstruction

DOMNameSpaceNode

DOMNameSpaceNode

DOMDocumentFragment

DOMDocumentFragment

DOMCharacterData

DOMCharacterData

DOMText

DOMText

DOMCdataSection

DOMCdataSection

DOMException DOMImplementation DOMNodeList DOMNamedNodeMap DOMXPath

Additional Classes

slide-60
SLIDE 60

DOM: Sample Document DOM: 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>

slide-61
SLIDE 61

DOM:Document Navigation DOM:Document Navigation

dom/navigate-2.php dom/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

slide-62
SLIDE 62

DOM: Navigation Optimized DOM: Navigation Optimized

dom/navigate-optimized.php dom/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"; } }

slide-63
SLIDE 63

DOM: Creating a Simple Tree DOM: Creating a Simple Tree

dom/create_simple_tree.php dom/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);

slide-64
SLIDE 64

DOM: Simple Tree Output DOM: 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>

slide-65
SLIDE 65

DOM: Modification DOM: Modification

Load with User Stream Load 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');

slide-66
SLIDE 66

DOM: Document Modification DOM: Document Modification

dom/modify.php dom/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>

slide-67
SLIDE 67

DOM: Document Modification DOM: 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); } } OR OR $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);

slide-68
SLIDE 68

DOM and Namespaces DOM 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>

slide-69
SLIDE 69

Dom and Namepsaces Dom and Namepsaces

dom/namespace.php dom/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[]");

slide-70
SLIDE 70

DOM and Xpath DOM and Xpath

dom/xpath/dom-xpath.xml dom/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>

slide-71
SLIDE 71

DOM and Xpath DOM and Xpath

dom/xpath/dom-xpath.php dom/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->query query("//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->evaluate evaluate("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->query query("//ec:book"); ("//ec:book"); $book = $nodelist->item(0); $book = $nodelist->item(0); $inventory = $xpath-> $inventory = $xpath->evaluate evaluate("sum(./@qty)", ("sum(./@qty)", $book $book); ); print "Total Books: ".$inventory."\n"; print "Total Books: ".$inventory."\n";

slide-72
SLIDE 72

DOM and Xpath Results DOM and Xpath Results

Book Title: Grapes of Wrath Book Title: Grapes of Wrath Total Books: 58 Total Books: 58 Total Books: 33 Total Books: 33

slide-73
SLIDE 73

Performing Validation Performing Validation

dom/validation/validate.php dom/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"; } }

slide-74
SLIDE 74

Performing Validation Results Performing Validation Results

DTD Validation: DTD Validation: Document Is Valid Document 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 11 Warning: 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 11 Warning: 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 valid Document is valid RelaxNG Validation: RelaxNG Validation: Document is valid Document is valid

slide-75
SLIDE 75

Extending DOM Classes Extending 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.

slide-76
SLIDE 76

Extending DOM Classes Extending DOM Classes

dom/extending/ dom/extending/extending.php

extending.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();

slide-77
SLIDE 77

DOM Object Scope DOM Object Scope

dom/extending/object_scope.php dom/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: customElement After Append: customElement After unset: DOMElement After unset: DOMElement Within changeit function: customElement Within changeit function: customElement Outside changeit(): DOMElement Outside changeit(): DOMElement

slide-78
SLIDE 78

DOM: registerNodeClass DOM: 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: customElement After Append: customElement After unset: customElement After unset: customElement Within changeit function: DOMElement Within changeit function: DOMElement Outside changeit(): customElement Outside changeit(): customElement

slide-79
SLIDE 79

DOM:Common Issues DOM:Common Issues

DOM Objects and Sessions

DOM Objects and Sessions

Removing Nodes while iterating a Nodeset skips

Removing Nodes while iterating a Nodeset skips nodes nodes

XML Tree contains garbled characters

XML Tree contains garbled characters

Extended class is not returned from property or

Extended class is not returned from property or method method

Elements not being returned by ID

Elements not being returned by ID

Entity errors are issues when loading a document

Entity errors are issues when loading a document

New DTD is not recognized by document

New DTD is not recognized by document

slide-80
SLIDE 80

XMLReader XMLReader

Forward moving stream based parser

Forward moving stream based parser

It is a Pull parser

It is a Pull parser

Based on the C# XmlTextReader API

Based on the C# XmlTextReader API

Advantages:

Advantages:

Low memory footprint

Low memory footprint

Namespace support

Namespace support

Simple API

Simple API

Validation support

Validation support

Advanced Feature Set

Advanced Feature Set

Faster Processing

Faster Processing

slide-81
SLIDE 81

XMLReader: Simple Example XMLReader: Simple Example

xmlreader/reader_simple.xml xmlreader/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 Paragraph First 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>

slide-82
SLIDE 82

XMLReader: Simple Example XMLReader: Simple Example

xmlreader/reader_simple.php xmlreader/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";

} } } }

slide-83
SLIDE 83

XMLReader: Simple Example XMLReader: Simple Example

RESULTS RESULTS

xmlns Attribute value: http://www.example.com/namespace-a xmlns Attribute value: http://www.example.com/namespace-a Local Name for Element: title Local Name for Element: title Namespace URI for Element: Namespace URI for Element: http://www.example.com/namespace-a

http://www.example.com/namespace-a

Element: para Element: para Element: a:section Element: a:section a:id=about a:id=about Element: title Element: title Element: para Element: para PI Target: php PI Target: php PI Data: echo 'Hi! This is PHP version ' . phpversion(); PI Data: echo 'Hi! This is PHP version ' . phpversion();

slide-84
SLIDE 84

XMLReader: Consuming Yahoo XMLReader: Consuming Yahoo Shopping Shopping

<?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">

< <Result Result> > < <Catalog Catalog ID="1991433722"> ID="1991433722"> < <Url Url><![CDATA[http://shopping.yahoo.com/p:Linksys. . .2]]></Url> ><![CDATA[http://shopping.yahoo.com/p:Linksys. . .2]]></Url> < <ProductName ProductName><![CDATA[Linksys WRT5. . .r Broadband ><![CDATA[Linksys WRT5. . .r Broadband Router]]></ProductName> Router]]></ProductName> < <PriceFrom PriceFrom>69.97</PriceFrom> >69.97</PriceFrom> < <PriceTo PriceTo>89.99</PriceTo> >89.99</PriceTo> <Thumbnail /><!-- child elements Url (CDATA), Height, Width --> <Thumbnail /><!-- child elements Url (CDATA), Height, Width --> < <Description Description><![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>

slide-85
SLIDE 85

XMLReader: Consuming Yahoo Shopping XMLReader: Consuming Yahoo Shopping

xmlreader/rest_yahoo_shopping.php xmlreader/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'));

slide-86
SLIDE 86

XMLReader: Consuming Yahoo Shopping XMLReader: Consuming Yahoo Shopping

xmlreader/rest_yahoo_shopping.php xmlreader/rest_yahoo_shopping.php function getTextValue($reader) { function getTextValue($reader) { if ($reader->nodeType != if ($reader->nodeType != XMLReader::ELEMENT

XMLReader::ELEMENT || $reader->isEmptyElement

|| $reader->isEmptyElement || ($reader->read() && $reader->nodeType == || ($reader->read() && $reader->nodeType == XMLReader::END_ELEMENT

XMLReader::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_ELEMENT

XMLReader::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(); }

} }

slide-87
SLIDE 87

XMLReader: Consuming Yahoo Shopping XMLReader: Consuming Yahoo Shopping

xmlreader/rest_yahoo_shopping.php xmlreader/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_ELEMENT

XMLReader::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();

} } } }

slide-88
SLIDE 88

XMLReader: Consuming Yahoo Shopping XMLReader: Consuming Yahoo Shopping

RESULTS (Abbreviated) RESULTS (Abbreviated) Catalog ID1990338714 Catalog ID1990338714 Url: Url: http://shopping.yahoo.com/p:Linksys%20Instant%20Broadband%20Ether http://shopping.yahoo.com/p:Linksys%20Instant%20Broadband%20Ether Fast%20Cable%2FDSL%20Router:1990338714 Fast%20Cable%2FDSL%20Router:1990338714 ProductName: Linksys Instant Broadband EtherFast Cable/DSL Router ProductName: Linksys Instant Broadband EtherFast Cable/DSL Router PriceFrom: 39.99 PriceFrom: 39.99 PriceTo: 72.71 PriceTo: 72.71 Description: <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

  • r office users to connect their computers to a cable or DSL modem and
  • r 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

  • f sharing files without fear of intruders hacking into the network. </P>
  • f sharing files without fear of intruders hacking into the network. </P>
slide-89
SLIDE 89

XMLReader: DTD Validation XMLReader: DTD Validation

xmlreader/validation/reader.xml xmlreader/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 Paragraph First 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>

slide-90
SLIDE 90

XMLReader: DTD Validation XMLReader: DTD Validation

xmlreader/validation/reader.php xmlreader/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; } }

slide-91
SLIDE 91

XMLReader: DTD Validation XMLReader: DTD Validation

RESULTS RESULTS 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

  • n line 2
  • n line 2

NOT VALID NOT VALID Element section was declared #PCDATA but contains non Element section was declared #PCDATA but contains non text nodes text nodes

slide-92
SLIDE 92

XMLReader: Relax NG Validation XMLReader: Relax NG Validation

xmlreader/validation/reader.rng xmlreader/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>

slide-93
SLIDE 93

XMLReader: Relax NG Validation XMLReader: Relax NG Validation

xmlreader/validation/reader-rng.php xmlreader/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; } }

slide-94
SLIDE 94

XMLReader: Relax NG Validation XMLReader: Relax NG Validation

RESULTS RESULTS 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

  • n line 2
  • n line 2

NOT VALID NOT VALID Did not expect element title there Did not expect element title there

slide-95
SLIDE 95

XMLReader: XML Schema Validation XMLReader: XML Schema Validation

xmlreader/validation/reader.xsd xmlreader/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>

slide-96
SLIDE 96

XMLReader: XML Schema Validation XMLReader: XML Schema Validation

xmlreader/validation/reader-xsd.php xmlreader/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+ REQUIRED LIBXML2-2.20+ REQUIRED

slide-97
SLIDE 97

XMLReader: XML Schema Validation XMLReader: XML Schema Validation

RESULTS RESULTS 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

  • n line 2
  • n line 2

NOT VALID NOT VALID Element '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.

slide-98
SLIDE 98

Tree Parsers Tree Parsers

Pros:

Pros:

Full navigation and modification of the XML

Full navigation and modification of the XML document document

Navigating and searching are extremely fast once

Navigating and searching are extremely fast once the tree is loaded into memory the 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 intensive

Memory intensive

slide-99
SLIDE 99

Streaming Parsers Streaming Parsers

Pros:

Pros:

Uses minimal memory

Uses minimal memory

Processing takes place immediately while the

Processing takes place immediately while the document is parsed document is parsed

Cons:

Cons:

Minimal to no navigation support (forward only)

Minimal to no navigation support (forward only)

No document editing capabilities

No document editing capabilities

slide-100
SLIDE 100

Raw Test Data Raw 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: 177KB 26KB 85.6MB 85.6MB XMLReader ext/xml SimpleXML DOM 0.238 0.930 6.583 6.623 XMLReader ext/xml SimpleXML DOM

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:

slide-101
SLIDE 101

XMLWriter XMLWriter

Lightweight and forward-only API for

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

Automatically escapes data

Automatically escapes data

Works with PHP 4.3+ available at

Works with PHP 4.3+ available at http://pecl.php.net/package/xmlwriter http://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.2

Part of core PHP distribution since PHP 5.1.2

slide-102
SLIDE 102

XMLWriter: Simple Example XMLWriter: Simple Example

xmlwriter/simple.php xmlwriter/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');

slide-103
SLIDE 103

XMLWriter: Simple Example XMLWriter: Simple Example

xmlwriter/simple.php xmlwriter/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); ?> ?>

slide-104
SLIDE 104

XMLWriter: Simple Example XMLWriter: Simple Example

xmlwriter/simple.php xmlwriter/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); ?> ?>

slide-105
SLIDE 105

XMLWriter: Simple Example XMLWriter: Simple Example

Results Results

<?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>

slide-106
SLIDE 106

XSL XSL

Used to transform XML data

Used to transform XML data

XSLT based on XPath

XSLT 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 transformation during a transformation

DOM nodes may be returned from PHP functions

DOM 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:key when using xsl:key

slide-107
SLIDE 107

XSL: XML Input Data XSL: XML Input Data

xsl/sites.xml xsl/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>

slide-108
SLIDE 108

XSL: Simple Transformation XSL: Simple Transformation

xsl/simple_stylesheet.xsl xsl/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>

slide-109
SLIDE 109

XSL: Simple Transformation XSL: Simple Transformation

xsl/simple_stylesheet.php xsl/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);

slide-110
SLIDE 110

XSL: Simple Transformation XSL: Simple Transformation

RESULTS RESULTS <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>

slide-111
SLIDE 111

XSL: Advanced Transformation XSL: Advanced Transformation

xsl/advanced_stylesheet.php xsl/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; }

slide-112
SLIDE 112

XSL: Advanced Transformation XSL: Advanced Transformation

xsl/advanced_stylesheet.php xsl/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 */

slide-113
SLIDE 113

XSL: Advanced Transformation XSL: Advanced Transformation

xsl/advanced_stylesheet.xsl xsl/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>

slide-114
SLIDE 114

XSL: Advanced Transformation XSL: Advanced Transformation

xsl/advanced_stylesheet.xsl xsl/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>

slide-115
SLIDE 115

XSL: Advanced Transformation XSL: Advanced Transformation

Results viewed through a browser Results viewed through a browser xsl/advanced_stylesheet.html xsl/advanced_stylesheet.html

Title: Re: Spreadsheet Writer URL: http://news.php.net/php.general/241446 Published: Thu, 07 Sep 2006 13:52:09 –0400 Title: Re: Spreadsheet Writer URL: http://news.php.net/php.general/241447 Published: Thu, 07 Sep 2006 13:52:09 -0400 Title: Re: Spreadsheet Writer URL: http://news.php.net/php.general/241448 Published: Thu, 07 Sep 2006 13:52:09 -0400

slide-116
SLIDE 116

Questions? Questions?

http://www.cdatazone.org/talks/quebec_2007/workshop.zip rrichards@ctindustries.net