crXml Reference Manual

 

This is  and xml parser and generator and manipulator.This one uses DOM XML Functions

 

Supports:

1.    XML Attributes

2.    Namespaces

3.    Namespaced attributes

4.    CDATA sections

 

Here I list some of the topics in this document that may be of greater interest.

 

1.    XML Generation

2.    XML Parsing

3.    Adding Namespace

4.    Adding a CDATA section

5.    PHP Code Generation for accessing a node

6.    XML Editing/Manipulation

 

XML Generation:

 

XML corresponding a crXml object is obtained by callng xml() method.

 

Please take a look at the examples.

 

Example 1:

 

Code

Output

$x = new crXml();                  

     

$x->person = "sandeep";

 

echo $x->xml();

<?xml version="1.0" encoding="UTF-8"?>
<person>sandeep</person>

 

Example 2:

     

Code

Output

$x=new crXml();

 

$x->records->name='sandeep';

echo $x->xml();

 

<?xml version="1.0" encoding="UTF-8"?>
<records>
      <name> sandeep </name>
</records>

 

Example 3:

 

Code

Output

$x=new crXml();

 

$x->records[5]->name='sandeep';

echo $x->xml();

 

<?xml version="1.0" encoding="UTF-8"?>
<records/>
<records/>
<records/>
<records/>
<records/>
<records>
      <name>sandeep</name>
</records> 

 

In the above example a value is assigned to the fifth `records` child of the root node.

As there are no presceding 4 nodes, they are created by the class itself.

 

Example 4: Adding attributes

 

Code

Output

$x = new  crXml();

 

$x->record->name = 'sandeep';

$x->record->name['sex'] = 'Male';

$x->record->name['age'] = '29';

 

echo $x->xml();

<?xml version="1.0" encoding="UTF-8"?>
<record>
      <name sex="Male" age="29"> sandeep </name>
</record>

 

 

Example 5: Adding Namespaces

A namespace declaration can be added to a node using the addNameSpace method.

 

This method accepts an array.

 

Thus multiple namespace declarations can be added to the node at once.

 

 

 

Code

Output

$crxml = new crXml();

 

$crxml->records->

addNameSpace(array('prfx'=>'http://google.com'));

 

$crxml->records->{'prfx:person'}->name = 'sandeep';

echo $crxml->xml();

 

<?xml version="1.0" encoding="UTF-8"?>
<records xmlns:prfx="http://google.com">
      <prfx:person>
            <name> sandeep </name>
      </prfx:person>
</records> 

 

 

Namespaced nodes can be added without using addNameSpace function also. See below examples.

 

An alternative syntax to generate a Namespaced node is to add the declaration of the namespace

in same node itself .

 

Here is how. This one does not use any function

 

Code

Output

$crxml = new crXml();

 

$crxml->records->{'http://google.com|person|prfx'}->name = 'sandeep';

echo $crxml->xml();

 

<?xml version="1.0" encoding="UTF-8"?>
<records>
      <prfx:person xmlns:prfx="http://google.com">
            <name>sandeep</name>
      </prfx:person>
</records>

 

In the above code the ‘|’ character is used to separate namespaceURI, nodeName and the prefix that

should be associated with that name space. The prefix part is optional. If omitted the node will

become the start of a default namespace

 

 

Example 6: Namespaced Attributes

 

Code

Output

 

$crxml = new  crXml();

$crxml->record->

addNameSpace(array('prfx'=>'http://google.com'));

 

$crxml->record->name = 'sandeep';

$crxml->record->name['prfx:sex'] = 'Male';

$crxml->record->name['age'] = '29';

 

echo $crxml->xml();

 

<?xml version="1.0" encoding="UTF-8"?>
<record xmlns:prfx="http://google.com">
      <name prfx:sex="Male" age="29">

          sandeep

      </name>
</record>

 

Please note that all the values can be retrived using the same notation used to assign it.

 

In the above example,

 

echo $crxml->record->name['prfx:sex']; would print “Male”.

 

echo $crxml->record->name; would print “sandeep”.

 

Example 7:

 

This example illustrates how to add many nodes with same name to a parent node.

 

<?php

 

$xml = new crXml();

 

$year = $xml->year;

 

foreach(range(1,12) as $m)

{

      $year->month[$m-1]->noOfDays =      date('t',mktime(0,0,0,$m,$m,2000));

      $year->month[$m-1]->shortName = date('M',mktime(0,0,0,$m,$m,2000));

      $year->month[$m-1]['name']=date('F',mktime(0,0,0,$m,$m,2000));

 

}

echo $xml->xml();

?>

 

Output:

 

<?xml version="1.0" encoding="UTF-8"?>
<year>
      <month name="January">
            <noOfDays>31</noOfDays>
            <shortName>Jan</shortName>
      </month>
      <month name="February">
            <noOfDays>29</noOfDays>
            <shortName>Feb</shortName>
      </month>
      <month name="March">
            <noOfDays>31</noOfDays>
            <shortName>Mar</shortName>
      </month>
      <month name="April">
            <noOfDays>30</noOfDays>
            <shortName>Apr</shortName>
      </month>
      <month name="May">
            <noOfDays>31</noOfDays>
            <shortName>May</shortName>
      </month>
      <month name="June">
            <noOfDays>30</noOfDays>
            <shortName>Jun</shortName>
      </month>
      <month name="July">
            <noOfDays>31</noOfDays>
            <shortName>Jul</shortName>
      </month>
      <month name="August">
            <noOfDays>31</noOfDays>
            <shortName>Aug</shortName>
      </month>
      <month name="September">
            <noOfDays>30</noOfDays>
            <shortName>Sep</shortName>
      </month>
      <month name="October">
            <noOfDays>31</noOfDays>
            <shortName>Oct</shortName>
      </month>
      <month name="November">
            <noOfDays>30</noOfDays>
            <shortName>Nov</shortName>
      </month>
      <month name="December">
            <noOfDays>31</noOfDays>
            <shortName>Dec</shortName>
      </month>
</year>

 

Now an echo $xml->year->month[2]['name']; would print ‘March’.Because nodes are indexed from 0.

 

Example 8:Adding a CDATA Section:

 

To add a cdata section, cast the string into an object while assigning it to nodes.

 

Code

Output

$xmlOne=new crXml();
$xmlOne->person->name 'sandeep';

 
$xmlOne->person->address = (object)"<this is a cdata section>";

 
echo 
$xmlOne->xml();

 

<?xml version="1.0" encoding="UTF-8"?>
<person>
      <name>sandeep</name>
      <address>
            <![CDATA[<this is a cdata section>]]>
      </address>
</person>

 

 

 

 

 

 

 

 

Example 9:Adding nodes with default Namespaces definitions ( Nodes of type <item xmlns = http://google.com> )

In the node  <item xmlns = http://google.com>  the xmlns = http://google.com is a default name space definition. All the child nodes with unprefixed node names belong to this namespace.

To add a node of this kind use the format   $crXml->{‘http://google.com|person’} = “sandeep”;

Please note the ‘|’ (pipe chatecter) to separate node name and namespace URI.

Code

Output

$xmlOne=new crXml();

$xmlOne->root->{'http://google.com|person'} = 'sandeep';

echo 
$xmlOne->xml();

<?xml version="1.0" encoding="UTF-8"?>
<root>
      <person xmlns="http://google.com">

           sandeep

      </person>
</root>

 

 

 

 

 

The value of same node can be retrived using same notation ie

echo $xmlOne->->root->{'http://google.com|person'} ;

will echo “sandeep”;

Example 10: Adding namespaced nodes (nodes with prefix:) with namespace definition in same node (Nodes of type <prfx:item xmlns:prfx=http://google.com>)

Nodes of type

<prfx:item xmlns:prfx=http://google.com>) contains the namespace definition of the prefix in the node itself.This type of  nodes can be created as follows.

Code

Output

<?php 
$xmlOne
=new crXml();

$xmlOne->root->{'http://google.com|person|prfx'} = 'sandeep';
 
echo 
$xmlOne->xml();
 

<?xml version="1.0" encoding="UTF-8"?>
<root>
      <prfx:person xmlns:prfx="http://google.com">

          Sandeep

      </prfx:person>
</root>

 

 

 

 

 

The value of same node can be retrived either using the prefix or using the namespace URI, as shown below

echo $xmlOne->root->{'prfx:person'};

or

echo $xmlOne->->root->{'http://google.com|person'} ;

will output ‘Sandeep”.

XML Parsing:

 

 

An XML String is loaded into the class using function loadXML();

 

    $x=new crXml();

    $xml=<<<EOB
    <?xml version="1.0" encoding="UTF-8"?>
        <records>
            <name>sandeep</name>
        </records>
    EOB;

    $crxml->loadXML($xml);

 

After this, Nodes can be accessed by a combination of object and array notation. to get the n-th child node of a node 'parentnode'

with name 'childnode' use notation

 

      $crXmlObj->.....->parentnode->childnode[n]

 

Please go through the following examples and please note the comments.

 

Example 1. Simple Example

       

<?php 
include 'crXml.php';

    $crxml=new crXml();

    $xml=<<<EOB
    <?xml version="1.0" encoding="UTF-8"?>
        <records>
            <name>sandeep</name>
        </records>
    EOB;

    $crxml->loadXML($xml);

    echo $crxml->records->name;  //echos 'sandeep' 
    ?>

 

Example 2. Accessing n-th child of a node

 

<?php 
   
include 'crXml.php';

    $crxml=new crXml();

    $xml=<<<EOB
    <?xml version="1.0" encoding="UTF-8"?>
        <records>
            <name>sandeep</name>
            <name>max</name>
        </records>
    EOB;

    $crxml->loadXML($xml);

    echo $crxml->records->name[1];  //echos 'max'

    ?>

 

Example 3: Dealing with NameSpaces

 

Type 1:

 

<?php 
    
$crxml=new crXml();
    $xml=<<<EOB
    <?xml version="1.0" encoding="UTF-8"?>
        <records xmlns:prf = 'http://yahoo.com'>
            <prf:name>sandeep</prf:name>
            <prf:name>max</prf:name>
        </records>
    EOB;

    $crxml->loadXML($xml);

    echo $crxml->records->{'prf:name'}[1];  //echos 'max'

 

Type 2: Accessing namespace without prefix(Default Namespaces).

 

<?php 

    $crxml=new crXml();
    $xml=<<<EOB
        <?xml version="1.0" encoding="UTF-8"?>
            <records xmlns = 'http://yahoo.com'>
                <name>sandeep</name>
                <name>max</name>
            </records>
    EOB;

    $crxml->loadXML($xml);
    
    $crxml->{'http://yahoo.com|records'}->name;     //  uses '|' charecter to separate namespace URI and nodename;echos 'sandeep'
    $crxml->{'http://yahoo.com|records'}->name[1];  //  echos 'max'

 

Type 3. accessing nodes with namespaces defenition in the same node

 

<?php 
    $crxml=new crXml();
    $xml=<<<EOB
    <?xml version="1.0" encoding="UTF-8"?>
        <prf:records xmlns:prf = 'http://yahoo.com'>
            <prf:name>sandeep</prf:name>
            <prf:name>max</prf:name>
        </prf:records>
    EOB;

    $crxml->loadXML($xml);
    echo $crxml->{'prf:records'}->{'prf:name'}[1];  // echos 'max'

 

The Search Function:

 

This is a very useful function that can actually generate the php code to access a certain node.

 

For example consider the following SOAP Response XML

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<GeteBayOfficialTimeResponse xmlns="urn:ebay:apis:eBLBaseComponents">
<Timestamp>2005-10-28T01:01:04.668Z</Timestamp>
<Ack>Success</Ack>
<Version>429</Version>
<Build>e429_intl_Bundled_1949355_R1</Build>
</GeteBayOfficialTimeResponse>
</soapenv:Body>
</soapenv:Envelope>


You load this xml into a crXml '$srcXML' object using loadXML($xmlStr) method. Now say, you need to access the timestamp node.

you only have to call the search() function on the $srcXML object. This is shown below.

 

print_r($srcXML->search('Timestamp'));


This prints the dump of the array returned by the search function.

 

Please note the 'accessStatement' element .

 

This element shows how the 'Timestamp' node should be accessed.

Array
(
[0] => Array
(
[nodeName] => Timestamp
[namespaceURI] => urn:ebay:apis:eBLBaseComponents
[nodeValue] => 2005-10-28T01:01:04.668Z
[accessStatement] => ...->{'soapenv:Envelope'}->{'soapenv:Body'}->{'urn:ebay:apis:eBLBaseComponents|GeteBayOfficialTimeResponse'}->{'urn:ebay:apis:eBLBaseComponents|Timestamp'}
)

)

Here accessElement contains

...->{'soapenv:Envelope'}->{'soapenv:Body'}->{'urn:ebay:apis:eBLBaseComponents|GeteBayOfficialTimeResponse'}->{'urn:ebay:apis:eBLBaseComponents|Timestamp'}

so an echo


$srcXML->{'soapenv:Envelope'}->{'soapenv:Body'}->{'urn:ebay:apis:eBLBaseComponents|GeteBayOfficialTimeResponse'}->{'urn:ebay:apis:eBLBaseComponents|Timestamp'}

Will echo its value here it is  '2005-10-28T01:01:04.668Z'

You can search namespaced nodes too using the search function. just use the nodename with prefix as it appears in XML.

for Eg:

 

$srcXML->search('soapenv:Body');

 

 

 

Example 4: Iterating over a nodes children.

 

The crXml object is iterable, so a simple foreach can be used to iterate over a node’s children. Please look at the below example.

 

<?php 

 

include 'crXml.php';

$xml = <<<EOB
<?xml version="1.0" encoding="UTF-8"?>
<year>
      <month name="January">
            <noOfDays>31</noOfDays>
            <shortName>Jan</shortName>
      </month>
      <month name="February">
            <noOfDays>29</noOfDays>
            <shortName>Feb</shortName>
      </month>
      <month name="March">
            <noOfDays>31</noOfDays>
            <shortName>Mar</shortName>
      </month>
</year>
EOB;

$x = new  crXml();

$x->loadXML($xml);

foreach($x->year as $k => $v) {
   
echo $k,  ',' $v['name'], ',' $v->shortName,"<br/>";
}

 

In the above foreach, the nodes name is returned in the $k, and the nodes value is returned in the $v.

 

Note that each $v is a crXml object. So its children and attributes can be accessed in manner described

 in previous examples.

 

So the above code outputs

 

month,January,Jan
month,February,Feb
month,March,Mar

 

XML Editing:

crXml can be used to modify an existing XML Documents. It can

1.    Assign new values to existing nodes,

2.    Add, edit and remove nodes,

3.    Add, edit and remove attributes.

4.    Add a node from another XML document 

Actually you can do anything explained in above sections with an existing XML document after it has been loaded using loadXML() method.

For Illustrating the above capabilities please go through the following examples.

Example 1.Simple value and attribute modification

<?php 
include 'crXml.php';

$x = new crXml();

$xmlStr = <<<EOB
<?xml version="1.0" encoding="UTF-8"?>
<records>
    <person age="15">
        <name>
            alex
        </name>
    </person>
    <person age="28">
        <name>
            sandeep
        </name>
    </person>
</records>
EOB;

$x->loadXML($xmlStr);

$x->records->person[1]['age'] = '30';    //sets second persons attribute to 30
$x->records->person[1]->name 'albert';  // sets child node ‘name’ of second person to ‘albert’

$x->records->person[2] = $x->records->person[1];  // create a third `person` node and assign it the value of second 'person' node.

echo $x->xml();

?>

Outputs XML:

<?xml version="1.0" encoding="UTF-8"?>
<records>
      <person age="15">
            <name>alex</name>
      </person>
      <person age="30">
            <name>albert</name>
      </person>
      <person>
            <name>albert</name>
      </person>
</records>

 

Example 2:Removing and Emptying a node:

Removing a node results in the removal of that node and all of its children. To remove a node, call the `remove` method on that node

Emptying a node results in the removal of all the children of that node. To empty a node, call the `emptyNode` method on that node.

$x->records->person[1]->remove();  removes the second person  node from the above XML resulting in

<?xml version="1.0" encoding="UTF-8"?>
<records>
      <person age="15">
            <name>alex</name>
      </person>
      <person>
            <name>albert</name>
      </person>
</records>

$x->records->person[1]->emptyNode();  removes the second persons child nodes from the above XML resulting in

<?xml version="1.0" encoding="UTF-8"?>
<records>
      <person age="15">
            <name>alex</name>
      </person>
      <person age="30"/>
      <person>
            <name>albert</name>
      </person>
</records>

Example 3: Copying Nodes from one XML document to another XML document.

Copying one node from one xml to another xml is as simple as an assignment.

Consider the following two very simple xml objects.

The crXml statements and the resulting xml are shown below

Consider that the source and destination xmls are loaded into two crXml objects $s and $d respectievely.

 

 

Source XML ($s)

Destination XML($d)

 

<?xml version="1.0" encoding="utf-8"?>
<records>
      <person age='25' sex='male'>
            <name>John</name>
      </person>
      <person age='35' sex='female'>
            <name>Ann</name>
      </person>
      <personNew
age='15' sex='female'>
            <name>Riya</name>
      </personNew>
</records>

 

<?xml version="1.0" encoding="utf-8"?>
<records>
      <person age='15' sex="male">
            <name>Max</name>
      </person>
      <person age='32' sex='female'>
            <name>Liz</name>
      </person>
</records>

 

 

 

$d->records->person[1] = $s->records->person[0];

<?xml version="1.0" encoding="UTF-8"?>
<records>
      <person age="15" sex="male">
            <name>Max</name>
      </person>
      <person age="25" sex="male">
            <name>John</name>
      </person>
</records>

The destination nodes attribute and child nodes are cleared.

 

The attributes and children from

Source node is copied to destination making the two nodes equalent.If the source node is of different namespace the namespace is not copied

$d->records->person[1] = $s->records->personNew;

<?xml version="1.0" encoding="UTF-8"?>
<records>
      <person age="15" sex="male">
            <name>Max</name>
      </person>
      <person age="15" sex="female">
            <name>Riya</name>
      </person>
</records>

Same as above,

The attributes and childnodes of destination node are deleted.

 

The attributes and children from

Source node are copied to destination making the two nodes equivalent. If the source node is of different namespace the namespace is not copied

$s->records->person[0]->appendTo($d->records);

<?xml version="1.0" encoding="UTF-8"?>
<records>
      <person age="15" sex="male">
            <name>Max</name>
      </person>
      <person age="32" sex="female">
            <name>Liz</name>
      </person>
      <person age="25" sex="male">
            <name>John</name>
      </person>
</records>

The source node is appended to the  child nodes of the destination

$d->records->person[1]->name $s->records->person[0]->name;

<?xml version="1.0" encoding="UTF-8"?>
  <records>
    <person age="15" sex="male"> 
            <name>Max</name> 
      </person>
      <person age="32" sex="female">
            <name>John</name>
      </person>
  </records>

 

$d->records->person[1]->appendNode(

crxml::factory("<newNode>nodeV<person/></newNode>")

);

<?xml version="1.0" encoding="UTF-8"?>

  <records>

      <person age="15" sex="male">

            <name>Max</name>

      </person>

      <person age="32" sex="female">

            <name>Liz</name>

            <newNode>newNodeValue</newNode>

      </person>

  </records>

The factory method used to generate a xml node, and append to the second person node.