With XML mappling, it is possible to export an XItem to XML or import it back. The mechanism is similar to O-R mapping. By default, all fields of the XItem are exported as attributes of an XML element, which name is equal to the class name. However, there are some parameters to tweak the result.
XML mapping works with PHP's DOM library (http://www.php.net/manual/en/book.dom.php). There are 2 important methods, $item->Export( $parent_element ) and $item->Import( $element ).
class Book extends XItem { public $Title; public $NumberOfPages; public static function FillMeta(XMeta $m){ $m->Title = XMeta::String(); $m->NumberOfPages = XMeta::IntegerOrNull(); } } $x = Book::Temp(); $x->Title = 'Test'; $x->NumberOfPages = 100; $dom = new DOMDocument(); $x->ExportXML($dom); echo $dom->SaveXML(); // // output: // // <?xml version="1.0" ?> // <Book id="FFFFFFFF" Title="Test" NumberOfPages="100" /> //
As with O-R mapping, there are some parameters to change the default XML mapping. First of all, use SetXmlTagName of the XMeta class to change the name of the element. In addition, you can use the WithXmlAlias of the XMetaField to change the name of each attribute. Furthermore, use WithIsXmlBound to remove the mapping of a field altogether.
class Book extends XItem { public $Title; public $NumberOfPages; public static function FillMeta(XMeta $m){ $m->SetXmlTagName('book'); $m->Title = XMeta::String()->WithIsXmlBound(false); $m->NumberOfPages = XMeta::IntegerOrNull()->WithXmlAlias('number-of-pages'); } } $x = Book::Temp(); $x->Title = 'Test'; $x->NumberOfPages = 100; $dom = new DOMDocument(); $x->ExportXML($dom); echo $dom->SaveXML(); // // output: // // <?xml version="1.0" ?> // <book id="FFFFFFFF" number-of-pages="100" /> //
Sometimes, the use of attributes is not good enough, because the field contains a long text that would be better presented as a separate element. This can change with the WithXmlBehaviour method:
class Book extends XItem { public $Title; public $NumberOfPages; public static function FillMeta(XMeta $m){ $m->SetXmlTagName('book'); $m->Title = XMeta::String()->WithXmlAlias('title')->WithXmlBehaviour(Xml::Element); $m->NumberOfPages = XMeta::IntegerOrNull()->WithXmlAlias('number-of-pages'); } } $x = Book::Temp(); $x->Title = 'Test'; $x->NumberOfPages = 100; $dom = new DOMDocument(); $x->ExportXML($dom); echo $dom->SaveXML(); // // output: // // <?xml version="1.0" ?> // <book id="FFFFFFFF" number-of-pages="100"> // <title>Test</title> // </book> //
Slaves (see advanced patterns) will be exported as sub-elements, unless they are opted out with WithIsXmlBound.
class Book extends XItem { public $Title; public $Chapters; public static function FillMeta(XMeta $m){ $m->Title = XMeta::String(); $m->Chapters = BookChapter::Meta()->idBook->Slave(); } } class BookChapter extends XItem { public $idBook; public $Title; public static function FillMeta(XMeta $m){ $m->idBook = XMeta::ID(); $m->Title = XMeta::String(); } } $x = Book::Temp(); $x->Title = 'Test'; $c = BookChapter::Temp(); $c->Title = 'Test chapter 1'; $c->idBook = $x->id; $x->Chapters[] = $c; $dom = new DOMDocument(); $x->ExportXML($dom); echo $dom->SaveXML(); // // output: // // <?xml version="1.0" ?> // <Book id="FFFFFFFF" Title="Test"> // <BookChapter id="FFFFFFFE" Title="Test chapter 1" /> // </Book> //
Importing XML uses the same mapping and is also based on PHP's DOM.
$dom = new DOMDocument(); $dom->loadXml(' <?xml version="1.0" ?> <Book id="FFFFFFFF" Title="Test"> <BookChapter id="FFFFFFFE" Title="Test chapter 1" /> </Book> '); $x = Book::Temp(); $x->ImportXml( $dom->documentElement );
Importing a DOMElement into an XItem will change only the fields that exist in the XML code and skip the rest.