php实现的数组转xml案例分析
本文实例讲述了php实现的数组转xml,分享给大家供大家参考,具体如下:
0x00 需求
最近要做百度、360、神马搜索的网站sitemap,三家的格式都是xml,然而具体的细节还有有差别的。
一开始用的是dom,没有使用sax,写了几段便觉得太傻了,想到有没有数组转xml的库呢?
0x01 array2xml
搜索了一下,还真有地址为git,于是开始撸起袖子开始干。
示例如下:
THE CODE:
$xml = new ArrayToXML();
print $xml->buildXML($input);
INPUT:
- $input = array('product' => array(
- '@id' => 7,
- 'name' => 'some string',
- 'seo' => 'some-string',
- 'ean' => '',
- 'producer' => array(
- 'name' => null,
- 'photo' => '1.png'
- ),
- 'stock' => 123,
- 'trackstock' => 0,
- 'new' => 0,
- 'pricewithoutvat' => 1111,
- 'price' => 1366.53,
- 'discountpricenetto' => null,
- 'discountprice' => null,
- 'vatvalue' => 23,
- 'currencysymbol' => 'PLN',
- '#description' => '',
- '#longdescription' => '',
- '#shortdescription' => '',
- 'category' => array(
- 'photo' => '1.png',
- 'name' => 'test3',
- ),
- 'staticattributes' => array(
- 'attributegroup' => array(
- 1 => array(
- '@name' => 'attributes group',
- 'attribute' => array(
- 0 => array(
- 'name' => 'second',
- 'description' => 'desc2',
- 'file' => '',
- ),
- 1 =>
- array(
- 'name' => 'third',
- 'description' => 'desc3',
- 'file' => '',
- ),
- )
- )
- )
- ),
- 'attributes' => array(),
- 'photos' => array(
- 'photo' => array(
- 0 => array(
- '@mainphoto' => '1',
- '%' => '1.png',
- ),
- 1 => array(
- '@mainphoto' => '0',
- '%' => '2.png',
- ),
- 2 => array(
- '@mainphoto' => '0',
- '%' => '3.png',
- )
- )
- )
- ));
OUTPUT (XML data):
- <?xml version="1.0" encoding="UTF-8"?>
- <data>
- <product >
- <description><[CDATA[]]></description>
- <longdescription><[CDATA[]]></longdescription>
- <shortdescription><[CDATA[]]></shortdescription>
- <name>some string</name>
- <seo>some-string</seo>
- <ean></ean>
- <producer>
- <name></name>
- <photo>1.png</photo>
- </producer>
- <stock>123</stock>
- <trackstock>0</trackstock>
- <new>0</new>
- <pricewithoutvat>1111</pricewithoutvat>
- <price>1366.53</price>
- <discountpricenetto></discountpricenetto>
- <discountprice></discountprice>
- <vatvalue>23</vatvalue>
- <currencysymbol>PLN</currencysymbol>
- <category>
- <photo>1.png</photo>
- <name>test3</name>
- </category>
- <staticattributes>
- <attributegroup name="attributes group">
- <attribute>
- <name>second</name>
- <description><p>desc2</p></description>
- <file></file>
- </attribute>
- <attribute>
- <name>third</name>
- <description><p>desc3</p></description>
- <file></file>
- </attribute>
- </attributegroup>
- </staticattributes>
- <photos>
- <photo mainphoto="1">1.png</photo>
- <photo mainphoto="0">2.png</photo>
- <photo mainphoto="0">3.png</photo>
- </photos>
- </product>
- </data>
可以看到,# 表示CDATA,@表示属性,%代表有属性时这个元素本身的值,非常简洁。
另外数组要把重复元素提到外面作为数组的key,重复元素的各种属性是数组的值,并不需要像上面那样指定 0、1、2索引,直接用就可以了。
0x02 改进
可是发现有一个bug,根节点不能以CDATA开始。
另外还缺少一个功能,CDATA和属性不能同时存在。
于是阅读源码,改进了这两项,提交给了作者,并被合并了。
我额外增加了一个符号 “!” ,当CDATA 和属性同时存在时,写法为:
- $input = [
- "key" =>[
- "@id" => 1,
- "!" => 2
- ]
- ]
- <key ><![CDATA[2]]></key>