My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
FirstLook  
Updated Sep 12, 2010 by bcl...@gmail.com

Consider the following class hierarchy:

    class Person {

        /** @XmlElement(string, first-name) */
        private $firstName;

        /** @XmlElement(string, last-name) */
        private $lastName;

        /** @XmlElement(date, birth-date) */
        private $birthDate;

        // getters and setters are skipped for brevity
    }

    abstract class Vehicle {
        /** @XmlAttribute */
        private $name;

        /** @XmlElement */
        private $description;

        /** @XmlElement(Person) */
        private $owner;

        // getters and setters are skipped for brevity
    }

    class Car extends Vehicle {

        /** @XmlAttribute(double) */
        private $liter;

        /** @XmlAttribute(int) */
        private $cylinder;

        /** @XmlAttribute(bool, automatic-transmission) */
        private $automaticTransmission;

        // getters and setters are skipped for brevity
    }

    class Boat extends Vehicle {

        /** @XmlAttribute(int) */
        private $deadweight;

        // getters and setters are skipped for brevity
    }

    class Bike extends Vehicle {

        /** @XmlElement(string, feature) */
        public $features = array();

    }

    /** @XmlRoot(garage) */
    class Garage {

        /** @XmlAttribute(int) */
        private $capacity;

        /**
         *  @XmlElement(Car, car)
         *  @XmlElement(Boat, boat)
         *  @XmlElement(Bike, bicycle)
         */
        private $vehicles;


        function __construct() {
            $this->vehicles = new ArrayObject();
        }

        // getters and setters are skipped for brevity
    }

There are the abstract Vehicle and three concrete vehicles: a Car, a Boat and a Bike. A vehicle belongs to a Person, and all of them are put into a Garage. I hope you'll excuse my fantasy of placing a sea ship there :)

Next let's create some fancy instances of them:

    $carmack = new Person();
    $carmack->setFirstName("John");
    $carmack->setLastName("Carmack");
    $carmack->setBirthDate(new DateTime("Aug 20, 1970"));

Carmack was the lead programmer of the id computer games Wolfenstein 3D, Doom, Quake. A lot of thanks to him!

    $gump = new Person();
    $gump->setFirstName("Forrest");
    $gump->setLastName("Gump");
    $gump->setBirthDate(new DateTime("1944-06-06"));

His momma always said, "Life was like a box of chocolates. You never know what you're gonna get."

    $me = new Person();
    $me->setFirstName("Alex");

Oh, it's just me.

    $ferrari = new Car();
    $ferrari->setName("Ferrari F50");
    $ferrari->setCylinder(12);
    $ferrari->setLiter(4.7);
    $ferrari->setAutomaticTransmission(false);
    $ferrari->setOwner($carmack);
    $ferrari->setDescription( "The F50 was introduced in 1995 to celebrate the company's 50th anniversary.");

For John Carmack, the idea of fancy offices is counterintuitive. "Most people would consider my twin turbo Ferrari F50 a fair amount of celebration," he says in response to Romero's comments.

    $bike = new Bike();
    $bike->setName("Avalanche 1.0 Disc");
    $bike->setDescription("The Avalanche 1.0 is for recreational riders looking for a mid-level mountain bike.");
    $bike->features[] = "Frame: GT NEW Triple Triangle design 6061 butted aluminum";
    $bike->features[] = "Tires: Kenda Nevegal, 26 x 2.10";
    $bike->features[] = "Brakes: Tektro Auriga comp, hydraulic";
    $bike->features[] = "Fork: Rock Shox Dart 3";
    $bike->features[] = "Chain: Shimano HG-53 Nine Speed";
    $bike->setOwner($me);

This is my bike!

    $taxi = new Car();
    $taxi->setName("Peugeot 406");
    $taxi->setAutomaticTransmission(true);
    $taxi->setDescription("In Taxi 3, the 406 is further upgraded to be able to travel in icy terrain.");

Samy Naceri's transport. But I'm not sure about automatic... It's just for example.

    $boat = new Boat();
    $boat->setName("Jenny");
    $boat->setDescription("Shrimp boat. After the area was hit by Hurricane Carmen, Forrest's boat was the only one left standing.");
    $boat->setDeadweight(200);
    $boat->setOwner($gump);

"If you're ever a shrimp boat captain, that's the day I'm an astronaut" (Lt. Dan)

    $garage = new Garage();
    $garage->setCapacity(5);
    $garage->getVehicles()->append($ferrari);
    $garage->getVehicles()->append($bike);
    $garage->getVehicles()->append($taxi);
    $garage->getVehicles()->append($boat);

Now, everything is in its right place and we're ready for serialization.

    require_once "path/to/lexa-xml-serialization.php";
    use Lexa\XmlSerialization\XmlSerializer;

    $dom = XmlSerializer::serialize($garage);

That's it.

$dom->formatOutput = true;
$dom->saveXML()

The two above lines will produce the following XML markup:

<?xml version="1.0"?>
<garage capacity="5">
  <car liter="4.7" cylinder="12" automatic-transmission="false" name="Ferrari F50">
    <description>The F50 was introduced in 1995 to celebrate the company's 50th anniversary.</description>
    <owner>
      <first-name>John</first-name>
      <last-name>Carmack</last-name>
      <birth-date>1970-08-20</birth-date>
    </owner>
  </car>
  <bicycle name="Avalanche 1.0 Disc">
    <feature>Frame: GT NEW Triple Triangle design 6061 butted aluminum</feature>
    <feature>Tires: Kenda Nevegal, 26 x 2.10</feature>
    <feature>Brakes: Tektro Auriga comp, hydraulic</feature>
    <feature>Fork: Rock Shox Dart 3</feature>
    <feature>Chain: Shimano HG-53 Nine Speed</feature>
    <description>The Avalanche 1.0 is for recreational riders looking for a mid-level mountain bike.</description>
    <owner>
      <first-name>Alex</first-name>
    </owner>
  </bicycle>
  <car automatic-transmission="true" name="Peugeot 406">
    <description>In Taxi 3, the 406 is further upgraded to be able to travel in icy terrain.</description>
  </car>
  <boat deadweight="200" name="Jenny">
    <description>Shrimp boat. After the area was hit by Hurricane Carmen, Forrest's boat was the only one left standing.</description>
    <owner>
      <first-name>Forrest</first-name>
      <last-name>Gump</last-name>
      <birth-date>1944-06-06</birth-date>
    </owner>
  </boat>
</garage>

Parsing it back to objects also doesn't require much effort:

$garage2 = XmlSerializer::unserialize($dom, "Garage");

Finally you may want to generate an XML Schema (XSD) for your classes:

$schema = XmlSerializer::generateSchema("Garage");

$schema->formatOutput = true;
$xml = $schema->saveXML();

The output will be:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="garage" type="Garage-Type"/>
  <xs:complexType name="Garage-Type">
    <xs:sequence>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:choice minOccurs="0">
          <xs:element name="car" type="Car-Type" minOccurs="0"/>
          <xs:element name="boat" type="Boat-Type" minOccurs="0"/>
          <xs:element name="bicycle" type="Bike-Type" minOccurs="0"/>
        </xs:choice>
      </xs:choice>
    </xs:sequence>
    <xs:attribute name="capacity" type="xs:integer"/>
  </xs:complexType>
  <xs:complexType name="Car-Type">
    <xs:sequence>
      <xs:element name="description" type="xs:string" minOccurs="0"/>
      <xs:element name="owner" type="Person-Type" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="liter" type="xs:double"/>
    <xs:attribute name="cylinder" type="xs:integer"/>
    <xs:attribute name="automatic-transmission" type="xs:boolean"/>
    <xs:attribute name="name" type="xs:string"/>
  </xs:complexType>
  <xs:complexType name="Boat-Type">
    <xs:sequence>
      <xs:element name="description" type="xs:string" minOccurs="0"/>
      <xs:element name="owner" type="Person-Type" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="deadweight" type="xs:integer"/>
    <xs:attribute name="name" type="xs:string"/>
  </xs:complexType>
  <xs:complexType name="Bike-Type">
    <xs:sequence>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="feature" type="xs:string" minOccurs="0"/>
      </xs:choice>
      <xs:element name="description" type="xs:string" minOccurs="0"/>
      <xs:element name="owner" type="Person-Type" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="name" type="xs:string"/>
  </xs:complexType>
  <xs:complexType name="Person-Type">
    <xs:sequence>
      <xs:element name="first-name" type="xs:string" minOccurs="0"/>
      <xs:element name="last-name" type="xs:string" minOccurs="0"/>
      <xs:element name="birth-date" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

Sign in to add a comment
Powered by Google Project Hosting