PHP [76] is a popular server-side script language embedded in HTML that
provides excellent string processing capabilities coupled with a good integration with a
relational data-base most often MySQL, but other databases can also be accomodated.
It features also many libraries for reading, creating and
transforming XML data [77]. In this section, we will show how to
use PHP for DOM, SAX and StAX parsing. We will use the same
algorithms and program organization that we used in Java (Chapter 8
and Chapter 9). We will
also describe how to transform XML data using XSL stylesheets and briefly show how
to use the SimpleXML
library that is useful for some simple cases.
To show how to process an existing XML structure, we will use the compacting
process that we programmed in Java in Section 8.1. In PHP, DOM
parsing is achieved simply by creating an instance of the Dom
class. This instance is a node
and its node type is given by the value of its property
nodeType
:
XML_ELEMENT_NODE
or XML_TEXT_NODE
. Information about a node
is available through properties nodeName
, attributes
(an
array
whose keys are attribute names), childNodes
(an
array
that can be iterated upon with foreach
) or
textContent
for text nodes.
Example 10.15. [DOMCompact.php
] Text compaction of the cellar book (Example 2.2) with PHP using the DOM model
Compare this program with Example 8.1.
1 <?php function compact_($node,$indent){if ($node->nodeType==XML_ELEMENT_NODE) {
print $node->nodeName."["; 5 $indent.=str_repeat(' ',strlen($node->nodeName)+1); $first=true; foreach ($node->attributes as $attrName => $attrValue) {
if(!$first)print "\n$indent"; print "@".$attrName."[".$attrValue->value."]"; 10 $first=false; } foreach ($node->childNodes as $child)
if($child->nodeType==XML_ELEMENT_NODE or strlen($child->textContent)>0 ){ 15 if(!$first)print "\n$indent"; compact_($child,$indent); $first=false;
} print "]"; 20 } else if ($node->nodeType==XML_TEXT_NODE)
print preg_replace("/ *\n? +/"," ",trim($node->textContent)); } $dom = new DomDocument();
25 $dom->preserveWhiteSpace = false; $dom->substituteEntities = true; $dom->load("php://stdin"); compact_($dom->documentElement,"");
print "\n"; 30 ?>
|
Prints the content of the XML node. Each line prefixed with an indentation, a string composed of the appropriate number of spaces. |
|
If the node is an element, prints the name of the node followed by an opening bracket and adds the appropriate number of spaces to the current indentation. |
|
Deals with attributes which are contained in an array over which we
iterate. For each attribute, prints a |
|
Processes all children with a |
|
If it is an element or a non-empty text node, recursively calls
|
|
Processes a text node by printing it and normalizing internal newlines. |
|
Parses the file by creating a new XML document from the content of the standard input. Sets parameters to that white space only nodes are not returned and that entities are replaced by their values before the XML processing. |
|
Call the compacting process on the document node with an empty indentation string. |
Because PHP programs are meant to be embedded in HTML, we now show how the HTML compacting process can be done.
Example 10.16. [compactHTML.php
] HTML compaction of the cellar book (Example 2.2) with PHP using the DOM model
Compare this program with Example 5.7.
1 <?php function tag($tag,$body,$attrs=""){return "<$tag".($attrs?" ":"")."$attrs>$body</$tag>"; } 5 function compact_($node){
if ($node->nodeType==XML_ELEMENT_NODE) {
$res=""; $attrs=""; 10 foreach ($node->attributes as $key => $value)
$attrs.=" $key='$value->value'"; $res.=tag("b",$node->nodeName)." ".$attrs; $children = $node->childNodes;
if($children->length>1){
15 $cs=""; foreach($children as $child) $cs.=compact_($child); $res.=tag("ul",$cs); } else 20 $res.=compact_($children->item(0));
return tag("li",$res); } else if ($node->nodeType==XML_TEXT_NODE){ return preg_replace("/ *\n? +/"," ",trim($node->nodeValue));
} 25 } $dom = new DomDocument();
$dom->preserveWhiteSpace = false; $dom->substituteEntities = true; 30 $file = $_GET['file']; $dom->load($file?$file:"php://stdin"); ?> <html xmlns="http://www.w3.org/1999/xhtml"> <head> 35 <title>HTML compaction of "<?php print $_GET['file']?>"</title> </head> <body> <ul> <?php print compact_($dom->documentElement,"")?>
40 </ul> </body> </html>
|
Defines a function that returns a string comprised of the string of the body of a tag (second parameter) wrapped by the start and end tag named with the first parameter. The third argument give a string of attributes that are added to the start tag. |
|
Returns a string corresponding to the content of the XML node. |
|
If the node is an element, the name of the node is and its attributes
are embedded in a |
|
Deals with attributes which are contained in an array over which we
iterate. For each attribute, prints its name and the
corresponding value separated by an equal sign. These attributes are
combined in a single string which is added after the name of the node
wrapped with a |
|
Gets the list of all children. |
|
If there are more than one child, accumulates the content of the children
and wrap it within an |
|
In the case of one child, returns its content. |
|
Processes a text node by normalizing its content. |
|
Parses the file by creating a new XML document from the content of a file named by the HTTP file parameter passed in the url. If this value is not set, the standard input content will be used. Sets parameters to that white space only nodes are not returned and that entities are replaced by their values before the XML processing. |
|
Calls the compacting process on the document node within an HTML
structure forming the shape of HTML page. |
In order to process an XML structure with the SAX approach, we will
use a similar compacting process to the one we programmed in Java in Section 8.2. SAX parsing is achieved by calling the
xml_parser_create
function. This call return a reference to a parser to
which we can set some options and then give an object in which are defined
call-back functions
that will be called during the parsing process.
Example 10.17. [SAXCompact.php
] Text compaction of the cellar book (Example 2.2) with PHP using the SAX model
Compare this program with Example 8.3.
1 <?php require 'CompactHandler.php';$handler = new CompactHandler(); 5 $parser = xml_parser_create("UTF-8");
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 10 xml_set_object($parser,$handler);
xml_set_element_handler($parser, "startElement", "endElement"); xml_set_character_data_handler($parser,"characters"); $fp = fopen("php://stdin","r");
15 while ($data = fread($fp, 4096)) { if (!xml_parse($parser, $data, feof($fp))) { die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser))); 20 } } print "\n"; xml_parser_free($parser); ?>
|
Makes sure that the appropriate |
|
Creates an instance of the SAX parser that will parse an UTF-8 input. Set some options, in particular, make sure that tag names are not returned in upper-case. |
|
Indicates to which object the parsing events of the
|
|
Starts the parsing process on the standard input. In order to save
space, the parsing is sent to the parser in chunks of 4K until the the
third parameter of |
SAX parsing events in PHP are sent to an event handler object in which are
defined some methods to deal with the parsing events. Unfortunately, the PHP SAX parser
does not collapse all contiguous character nodes in a single one, so the character
content must be accumulated in the $chars
variable which is then output
before dealing with a start or end tag.
Example 10.18. [CompactHandler.php
] PHP SAX handler for text
compacting an XML file such as that of Example 2.2
Compare this program with Example 8.4.
1 <?php class CompactHandler { var $closed, $indent, $chars;5 function CompactHandler(){
$this->closed=false; $this->indent=0; $this->chars=""; } 10 function startElement($parser, $localname, array $attributes){
$this->flushChars(); if ($this->closed) { print "\n".str_repeat(' ',$this->indent); 15 $this->closed=false; } $this->indent+=1+strlen($localname);
print $localname."["; $first=true; 20 foreach ($attributes as $attrName => $attrValue){
if(!$first)print "\n".str_repeat(' ',$this->indent); print "@".$attrName."[".$attrValue."]"; $first=false; $this->closed=true; 25 } } function endElement($parser, $localname){
$this->flushChars(); 30 print "]"; $this->closed=true; $this->indent-=1+strlen($localname); } 35 function characters($parser, $text){
if(strlen(trim($text))>0){ if ($this->closed) { print "\n".str_repeat(' ',$this->indent); $this->closed=false; 40 } $this->chars=$this->chars.trim($text); } } 45 function flushChars(){
if (strlen($this->chars)>0) { if ($this->closed) { print "\n".str_repeat(' ',$this->indent); $this->closed=false; 50 } print preg_replace("/ *\n? +/"," ",$this->chars); $this->closed=true; $this->chars=""; } 55 } } ?>
|
Declares variables to save the state of the parsing processing between calls to parsing call-back methods. |
|
Initializes two instance variables needed to output the element with the correct indentation and one to accumulate the character content of successive character nodes. |
|
When a new element is started, outputs the content of last character nodes and finishes the current indentation if needed. |
|
Updates the current indentation by adding the length of the element name. |
|
Prints the first attribute on the same line and the others on the subsequent lines properly indented. |
|
When an element finishes, outputs the contents of the last character nodes and closes the current bracket and updates the current indentation. |
|
For a non-empty text node, ends current line if needed and adds its
contents to the |
|
Ends the current indentation and output the normalized content of the
|
Compare this program with Example 8.5.
Pull parsing in PHP is done using an instance of the XMLReader
class which
defines a method to move the cursor forward in the XML file (read()
) and
attributes to test the content of the current token (nodetype
,
hasAttributes
and name
). Contrarily to the standards, the PHP
pull parser does not return a start and end tag for an empty element, but it instead
only a single element that can be checked with the isEmptyElement
method.
Example 10.19. [StAXCompact.php
] Text compaction of the cellar book (Example 2.2) with PHP using the StAX model
1 <?php function compact_($xmlsr,$indent){if($xmlsr->nodeType==XMLReader::ELEMENT){
print $xmlsr->name."["; 5 $indent.=str_repeat(' ',strlen($xmlsr->name)+1); $first=true; if($xmlsr->hasAttributes){
while($xmlsr->moveToNextAttribute()){ if(!$first)print "\n$indent"; 10 print "@".$xmlsr->name."[".$xmlsr->value."]"; $first=false; } } // Warning: PHP does not return an END_ELEMENT on a empty tag if(!$xmlsr->isEmptyElement)
15 while(true){ do {$xmlsr->read();} while ($xmlsr->nodeType==XMLReader::SIGNIFICANT_WHITESPACE); if($xmlsr->nodeType==XMLReader::END_ELEMENT)break; if($first)$first=false; 20 else print "\n$indent"; compact_($xmlsr,$indent);
} print "]"; } else if ($xmlsr->nodeType==XMLReader::TEXT) 25 print preg_replace("/ *\n? +/"," ",trim($xmlsr->value));
else { die("STRANGE NODE:".$xmlsr->nodeType."\n"); } } 30 $xmlsr = new XMLReader();
$xmlsr->open("php://stdin"); $xmlsr->setParserProperty(XMLReader::SUBST_ENTITIES,true); while ($xmlsr->nodeType!=XMLReader::ELEMENT)$xmlsr->read();
35 compact_($xmlsr,"");
print "\n"; ?>
|
Method to compact from the current token. As there is already a
|
|
If it is a start element tag, outputs the name of the element followed by an opening bracket and update the current indentation. |
|
Outputs each attribute name and value all indented except the first
one. Attributes are obtained by iteration using the the
|
|
Loops on children nodes that are not whitespace and compacts each of them with the correct indentation. Some care must be taken not to call this process on an empty tag (i.e. without any children node) because the PHP parser does not return the corresponding end tag. |
|
Recursive call to the compacting process. |
|
Prints the normalized character content. |
|
Creates a new stream parser, indicates that it will parse the standard input and that entities must be substituted by the parse. |
|
Ignores the tokens that come before the first element (e.g. processing instructions). |
|
Calls the compacting process with the current token and then prints a newline to flush the content of the last line. |
In order to demonstrate the creation of new XML document, we will parse the
compact form produced in Section 10.3.1 or in Section 10.3.2 like we did in Chapter 9. We
first need a way to access appropriate tokens corresponding to
important signals in the input file. This is achieved by defining a
CompactTokenizer
class (Example 10.20) that
will return opening and closing square brackets, at-signs and the rest as a single
string. Newlines will also delimit tokens but will be ignored in the document
processing. The file is processed by a series of calls to nextToken
or
skip
. skip
provides a useful redundancy check for tokens
that are encountered in the input but are ignored for output.
Example 10.20. [CompactTokenizer.php
] Specialized string scanner that
returns tokens of compact form.
Compare this program with Example 9.1.
1 <?php class CompactTokenizer {var $index, $tokens; 5 function CompactTokenizer($file){
global $index,$tokens; $tokens = preg_split("/\n|(\[|\]|@)/", file_get_contents($file), -1,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE); 10 $index = 0; } function getToken(){
global $tokens,$index; 15 $token = $index<count($tokens)?$tokens[$index]:false; return $token; } function nextToken(){
20 global $tokens,$index; do { $index=$index+1; $token = $this->getToken(); if($token==false)break; 25 $token=trim($token); } while (strlen($token)==0); return $token; } 30 function skip($sym){
if($this->getToken()==$sym) return $this->nextToken(); die("skip:$sym expected but ".$this->getToken()." found. index=$index"); } 35 } ?>
|
Defines the |
|
Initializes the |
|
Check that the index of the current token is within the bounds of the array and set it to false otherwise. Return it. |
|
Gets the next token but skip those containing only whitespace. It returns the value of the current token. |
|
Checks that the current token is the same as the one given as parameter and retrieves the next one. If the current token does not match, then stop the program by indicating the expected token and the one found with the content of the current line. |
In PHP, the node
creation and child addition is using DOM methods
createElement()
, appendChild()
and createTextNode()
.
The attributes of a node are
added using the setAttribute()
method.
Example 10.21. [DOMExpand.php
] PHP compact form parsing to create an
XML document
A sample input for this program is Example 5.8 , which should yield Example 2.2. Compare this program with Example 9.2.
1 <?php require 'CompactTokenizer.php';function expand($elem){
5 global $st,$dom; $st->skip('['); while($st->getToken()=='@'){ // process attributes
$attName=$st->skip("@"); $st->nextToken(); 10 $elem->setAttribute("$attName",$st->skip("["));
$st->nextToken(); $st->skip("]"); } while ($st->getToken()!=false && $st->getToken()!="]") {
15 $s = trim($st->getToken()); // process children $st->nextToken(); if($st->getToken()=="[") expand($elem->appendChild($dom->createElement($s)));
else 20 $elem->appendChild($dom->createTextNode($s));
} $st->skip("]"); } 25 $st = new CompactTokenizer('php://stdin');
$dom = new DOMDocument();
$rootname = $st->getToken();
while($st->nextToken()!='[') $rootname=$st->getToken(); 30 expand($dom->appendChild($dom->createElement($rootname)));
$dom->formatOutput=true;
print $dom->saveXML(); 35 ?>
|
Ensures that the |
|
Adds the content of the file corresponding to the children of the
current node to the |
|
Because all attribute names start with an |
|
Adding an attribute is done by calling the
|
|
All children are then processed in turn until a closing square bracket
is encountered. |
|
A new element named |
|
A text node is added as the last child of the current element. |
|
Creates the tokenizer on the standard input. |
|
Initializes a new XML document. |
|
The name of the root is the first token immediately followed by an opening square bracket. |
|
Creates the root node which is filled in by a call to |
|
Serializes the document on the standard output. Sets a flag so that
the XML is properly indented. Serialization is done using the
|
PHP also allows other ways of dealing with XML files, the simplest of which is
to apply an XSLT stylesheet on a loaded DOM structure. Currently, only XSLT
1.0 stylesheets can be used without having to link with external Java classes using a
PHP/Java bridge. The following example shows how to perform the
transformation defined by the Example 5.9 stylesheet. As the PHP
transformation is performed by xsltproc
that does not deal very well with
entities, for this case, we had to modify our original stylesheet Example 5.9 by replacing all
entities references by their values. The resulting XSLT compact-php.xsl
is not given
here but it is available on the companion web site.
Example 10.22. [XSLcompact.php
] PHP compaction of an XML file using an
XSLT stylesheet.
Application of an XSLT stylesheet on an XML file. Here we use a modified version Example 5.9 to produce a compact version of an XML file.
1 <?php $xml = new DOMDocument();$xml->load("php://stdin"); 5 $xsl = new DOMDocument();
$xsl->load('compact-php.xsl'); $proc = new XSLTProcessor();
$proc->importStyleSheet($xsl); 10 $proc -> setParameter(null, 'name','value'); // unused in this example print $proc->transformToXML($xml);
?>
|
Initializes the DOM structure for the instance file to transform and loads the file, here we deal with the standard input. |
|
Initializes the DOM structure for the transformation stylesheet and loads it. |
|
Configures the transformation processor with the stylesheet and sets some parameters (unused here) |
|
Serializes the output of the transformer on the instance file. |
For simple reading and manipulation of information of an XML file, one might
consider the SimpleXML
extension which, upon loading an XML file,
translates its the tree structure into a PHP object, an instance of the
SimpleXMLElement
class, that can be processed using the usual property
selectors and array iterators. As in PHP arrays are zero-based contrarily to XPath
in which elements are numbered starting at 1, some care must be given when translating
the expressions from one to the other. It is also possible to use XPath expressions
to select elements in this structure. Methods are provided to get the name of an
element, its attributes and its children nodes. Although it is possible
to deal with namespaces, their use is error-prone. The type of object created by
SimpleXML
is particular, so its uses should be kept for simple
operations and extraction of XML data. When an SimpleXMLElement
instance is compared or combined with other variables such as integers or strings, it
must be casted into the appropriate type before being used. Moreover, SimpleXML
has no provision
for mixed content, so for generality the DOM approach should be preferred, but it can
be useful in some cases.
Example 10.23 shows the use of SimpleXMLExpressions to access some information in Example 2.2. The expressions correspond to the examples given in Example 4.1.
Example 10.23. [SimpleXMLPath.php
] SimpleXML file loading followed by PHP
SimpleXML
expressions
SimpleXML
file loading followed by PHP expressions corresponding to the XPath
expressions of Example 4.1.
1 <?php $cellarbook = simplexml_load_file("CellarBook.xml");p("/cellar-book/owner",
5 $cellarbook->owner); p("/cellar-book/cellar/wine[quantity<2]", $cellarbook->xpath("/cellar-book/cellar/wine[quantity<2]")); p("/cellar-book/cellar/wine[1]", $cellarbook->cellar->wine[0]); 10 p("//postal-code/..", $cellarbook->xpath("//postal-code/..")); p("/cellar-book/owner/street", $cellarbook->owner->street); foreach ($cellarbook->cellar->wine as $w) { 15 p("//wine/@code",$w["code"]); } foreach ($cellarbook->children("http://www.iro.umontreal.ca/lapalme/wine-catalog")-> children() as $w){p("//cat:wine/@code",$w["code"]); } 20 p("/cellar-book/cellar/wine[1]/comment", $cellarbook->cellar->wine[0]->comment); $sum=0; foreach($cellarbook->cellar->wine as $w){ $sum+=(int)$w->quantity; 25 } p("sum(/cellar-book/cellar/wine/quantity)",$sum); print("for \$w in //wine return concat(\$w/quantity,':',//cat:wine/@code[.=\$w/@code]/../@name) 30 "); foreach($cellarbook->cellar->wine as $w){ foreach ($cellarbook-> children("http://www.iro.umontreal.ca/lapalme/wine-catalog") ->children() as $catw){ 35 if((string)$w["code"] == (string)$catw["code"]) print($w->quantity.":".$catw["name"]."\n"); } } print("---------------\n"); 40 $cheapFrenchWines=array(); foreach ($cellarbook->children("http://www.iro.umontreal.ca/lapalme/wine-catalog") ->children() as $catw){ if((string)$catw->origin->country=="France" && (int)$catw->price<20) 45 array_push($cheapFrenchWines,$catw["name"]); } p("//cat:wine[cat:origin/cat:country='France' and cat:price&lt;20]", $cheapFrenchWines); 50 function p($xpath,$sxo){
print("$xpath\n"); var_dump($sxo); print("---------------\n"); } 55 ?>
|
Loads the file given as parameter and returns the root element. |
|
List of example expressions. As comparison, the corresponding
XPath is given as a string, followed by the |
|
Prints the string with the XPath expression, the structure
returned by the evaluation of the expression. |
In order to illustrate the manipulation of SimpleXML structures, we give in Example 10.24 a version to produce a compact version of an XML
file. We simply parse (load) the file and the SimpleXML structure is built in memory. It
is then a simple matter of traversing this structure to produce a compact version of the
file.As a SimpleXMLElement
instance has only one slot for its
character content, it cannot cope
correctly with mixed content elements. Some information is lost in this
process. For example, all the text nodes in the food-pairing
element of
the first wine in the catalog will be concatenated as a single text node. When the
SimpleXML is printed in compact form, then first the text child is printed and then
the element children afterwards.
Example 10.24. [SimpleXMLCompact.php
] PHP compaction of an XML file
using a SimpleXML
.
Compaction of an XML file by first creating a SimpleXML
object
and the traversing it with standard PHP iterators to create a compact version of the
file.
1 <?php function compact_($sxelem,$indent){print $sxelem->getName()."[";
$indent.=str_repeat(' ',strlen($sxelem->getName())+1); 5 $first=true; foreach ($sxelem->attributes() as $attname => $attvalue) {
if(!$first)print "\n$indent"; print "@{$attname}[$attvalue]"; $first=false; 10 } $text = trim($sxelem);
if(strlen($text)){ print preg_replace("/ *\n? +/"," ",$text); $first=false; 15 } $children = $sxelem->children();
foreach ($children as $child){ if(!$first)print "\n$indent"; compact_($child,$indent);
20 $first=false; } print "]"; } 25 $dom = simplexml_load_file('php://stdin');
compact_($dom,"");
print "\n"; ?>
|
Function to compact a simple xml object (first parameter) with each
new line preceded by an indentation given by the second parameter. As
|
|
Prints the name of the element followed by an open bracket and updates the indentation by adding spaces corresponding to the number of characters in the element name. |
|
Prints the array of attributes on different lines except for the
first. The name of the attribute is preceded by |
|
If there is text content, prints it. The text is normalized by replacing contiguous spaces and new lines by a single space. Spaces at the start and end are removed first. Beware that the content is the concatenation of all child text nodes, so this is problematic in the case of mixed content elements. |
|
if the element has children, compacts them, a new line is output if it is not the first child. |
|
Calls |
|
Reads an XML instance file, here the standard input and keeps a reference on the root node. |
|
Calls the compacting function on the root element with an empty indentation. |
Example 10.25 follows the same structure as Example 10.21 to expand a compact form into a
SimpleXMLElement
structure. It uses the tokenizer of Example 10.20 to read the file. It recursively creates the
XML structure as it processes the file. As the PHP library does not provide an indented form
of the XML string, we provide one here as another illustration of
SimpleXMLElement
use.
Example 10.25. [SimpleXMLExpand.php
] PHP compact form parsing to create a
SimpleXMLElement
document
A sample input for this program is Example 5.8 , which should yield a file equivalent to Example 2.2 except for the mixed content elements. Compare this program with Example 9.2.
1 <?php require 'CompactTokenizer.php';function expand($elem){
5 global $st; $st->skip('['); while($st->getToken()=='@'){ // process attributes
$attName=$st->skip("@"); $st->nextToken(); 10 $elem->addAttribute("$attName",$st->skip("["));
$st->nextToken(); $st->skip("]"); } while ($st->getToken()!=false && $st->getToken()!="]") {
15 $s = trim($st->getToken()); // process children $st->nextToken(); if($st->getToken()=="[") { expand($elem->addChild($s));
} else 20 $elem[0]=$s; // add a text node
} $st->skip("]"); } 25 $st = new CompactTokenizer('php://stdin');
$rootname = $st->getToken();
while($st->nextToken()!='['){ $rootname=$st->getToken(); } 30 $sxelem = new SimpleXMLElement("<$rootname/>");
expand($sxelem);
print ppXML($sxelem,"");
35 function ppXML($sxelem,$indent){
$res=""; $name = $sxelem->getName(); $res.="$indent<$name"; 40 if(count($sxelem->attributes()>0))
foreach ($sxelem->attributes() as $attname => $attvalue) $res.=" ".$attname.'="'.$attvalue.'"'; $text = trim((string) $sxelem); if($sxelem->count()==0 && strlen($text) == 0) 45 $res.="/>\n";
else if($sxelem->count()==0) $res.=">$text</$name>\n";
else { $res.=">$text\n";
50 foreach ($sxelem->children() as $child) $res.=ppXML($child,$indent." "); $res.="$indent</$name>\n"; } return $res; 55 } ?>
|
Ensures that the |
|
Adds the content of the file corresponding to the children of the
current node to the |
|
Because all attribute names start with an |
|
Adding an attribute is done by calling the
|
|
All children are then processed in turn until a closing square bracket
is encountered. |
|
A new element named |
|
A text node is added as the child of the current element. As there is
no explicit method to specify text content, we assign the text content to the first
array position of the |
|
Creates the tokenizer on the standard input. |
|
The name of the root is the first token immediately followed by an opening square bracket. |
|
Creates the root node as a |
|
The root node which is filled in by a call to |
|
Serializes the document on the standard output by calling the |
|
Recursive function to create and indented string for the current
element. The |
|
Outputs the name of element followed by its attributes on a single line. |
|
If there is no text content and no children nodes, closes the current tag. |
|
If there are not children node, outputs the text and closes the tag. |
|
Close the current tag followed by possible text. Recursively process each children and concatenates their result in the current string output. |