Passing PHP associative arrays to and from XML
是否有一种简单的方法可以将PHP关联数组与XML进行封送处理? 例如,我有以下数组:
1 2 3 4 5 6 7
| $items = array("1","2",
array(
"item3.1" =>"3.1",
"item3.2" =>"3.2"
"isawesome" => true
)
); |
如何在尽可能少的行中将其转换为类似于以下XML的内容,然后再次返回?
1 2 3 4 5 6 7 8 9
| <items>
<item>1</item>
<item>2</item>
<item>
<item3_1>3.1</item3_1>
<item3_2>3.2</item3_2>
<isawesome>true</isawesome>
</item>
</items> |
我真的不在乎是否需要稍微更改数组结构,或者输出的XML是否与上面的示例不同。 我一直在尝试使用PHP的XMLReader和XMLWriter,但是文档非常糟糕,因此生成的代码看起来与我的感觉不一样:
1 2
| $xml = SomeXMLWriter::writeArrayToXml($items);
$array = SomeXMLWriter::writeXmlToArray($xml); |
在没有编写自己的自定义类的情况下,获取PHP数组的基本原始XML转储真的比这难吗?
我尽量避免梨。 除了配置方面的麻烦之外,我从未使用过使用过的任何软件包。
SimpleXML非常适合您使用。
对于那些不使用PEAR软件包但已安装PHP5的用户。这为我工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| /**
* Build A XML Data Set
*
* @param array $data Associative Array containing values to be parsed into an XML Data Set(s)
* @param string $startElement Root Opening Tag, default fx_request
* @param string $xml_version XML Version, default 1.0
* @param string $xml_encoding XML Encoding, default UTF-8
* @return string XML String containig values
* @return mixed Boolean false on failure, string XML result on success
*/
public function buildXMLData($data, $startElement = 'fx_request', $xml_version = '1.0', $xml_encoding = 'UTF-8') {
if(!is_array($data)) {
$err = 'Invalid variable type supplied, expected array not found on line '.__LINE__." in Class:".__CLASS__." Method:".__METHOD__;
trigger_error($err);
if($this->_debug) echo $err;
return false; //return false error occurred
}
$xml = new XmlWriter();
$xml->openMemory();
$xml->startDocument($xml_version, $xml_encoding);
$xml->startElement($startElement);
/**
* Write XML as per Associative Array
* @param object $xml XMLWriter Object
* @param array $data Associative Data Array
*/
function write(XMLWriter $xml, $data) {
foreach($data as $key => $value) {
if(is_array($value)) {
$xml->startElement($key);
write($xml, $value);
$xml->endElement();
continue;
}
$xml->writeElement($key, $value);
}
}
write($xml, $data);
$xml->endElement();//write end element
//Return the XML results
return $xml->outputMemory(true);
} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Xml {
public static function from_array($arr, $xml = NULL)
{
$first = $xml;
if($xml === NULL) $xml = new SimpleXMLElement('<root/>');
foreach ($arr as $k => $v)
{
is_array($v)
? self::from_array($v, $xml->addChild($k))
: $xml->addChild($k, $v);
}
return ($first === NULL) ? $xml->asXML() : $xml;
}
public static function to_array($xml)
{
$xml = simplexml_load_string($xml);
$json = json_encode($xml);
return json_decode($json,TRUE);
}
}
$xml = xml::from_array($array);
$array = xml::to_array($xml); |
我遇到了一些相同的问题,因此我创建了两个类:
BXML
扩展SimpleXml并更正其某些问题的类。就像无法添加CData节点或Comment节点一样。我还添加了一些其他功能,例如使用php流功能添加子节点$oXml->AddChild("file:///user/data.xml")或添加XML字符串子节点(如$oXml->AddChild("yes");),但是基本上我只是想解决simpleXML问题。
bArray
我扩展了ArrayObject类,以便所有数组功能都可以面向对象且一致,因此您无需记住array_walk按引用对数组进行操作,而array_filter按值对数组进行操作。因此,您可以执行$oArray->flip()->Reverse()->Walk(/*callback*/);之类的操作,然后仍然以通常希望$oArray[key]的方式访问该值。
两种方法都将自己输出为Arrays和Xml,因此您可以在它们之间无缝跳转。因此,您可以$oXml->AsArray();或$oArray->AsXml();我发现执行此操作比在array2xml或xml2array方法之间不断地来回传递要容易得多。
http://code.google.com/p/blibrary/source
可以重写这两个类以创建您选择的自定义类,并且可以彼此独立使用。
嘿,@ Conrad我只是修改您的代码以与数字数组配合使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| /**
* Build A XML Data Set
*
* @param array $data Associative Array containing values to be parsed into an XML Data Set(s)
* @param string $startElement Root Opening Tag, default fx_request
* @param string $xml_version XML Version, default 1.0
* @param string $xml_encoding XML Encoding, default UTF-8
* @return string XML String containig values
* @return mixed Boolean false on failure, string XML result on success
*/
public static function arrayToXML($data, $startElement = 'fx_request', $xml_version = '1.0', $xml_encoding = 'UTF-8'){
if(!is_array($data)){
$err = 'Invalid variable type supplied, expected array not found on line '.__LINE__." in Class:".__CLASS__." Method:".__METHOD__;
trigger_error($err);
if($this->_debug) echo $err;
return false; //return false error occurred
}
$xml = new XmlWriter();
$xml->openMemory();
$xml->startDocument($xml_version, $xml_encoding);
$xml->startElement($startElement);
/**
* Write XML as per Associative Array
* @param object $xml XMLWriter Object
* @param array $data Associative Data Array
*/
function write(XMLWriter $xml, $data){
foreach($data as $key => $value){
if (is_array($value) && isset($value[0])){
foreach($value as $itemValue){
//$xml->writeElement($key, $itemValue);
if(is_array($itemValue)){
$xml->startElement($key);
write($xml, $itemValue);
$xml->endElement();
continue;
}
if (!is_array($itemValue)){
$xml->writeElement($key, $itemValue."");
}
}
}else if(is_array($value)){
$xml->startElement($key);
write($xml, $value);
$xml->endElement();
continue;
}
if (!is_array($value)){
$xml->writeElement($key, $value."");
}
}
}
write($xml, $data);
$xml->endElement();//write end element
//returns the XML results
return $xml->outputMemory(true);
} |
所以您可以将其转换为:
1 2 3 4 5 6 7 8 9 10 11 12 13
| $mArray["invitations"]["user"][0]["name"] ="paco";
$mArray["invitations"]["user"][0]["amigos"][0] = 82;
$mArray["invitations"]["user"][0]["amigos"][1] = 29;
$mArray["invitations"]["user"][0]["amigos"][2] = 6;
$mArray["invitations"]["user"][1]["name"] ="jose";
$mArray["invitations"]["user"][1]["amigos"][0] = 43;
$mArray["invitations"]["user"][1]["amigos"][1]["tuyos"] = 32;
$mArray["invitations"]["user"][1]["amigos"][1]["mios"] = 79;
$mArray["invitations"]["user"][1]["amigos"][2] = 11;
$mArray["invitations"]["user"][2]["name"] ="luis";
$mArray["invitations"]["user"][2]["amigos"][0] = 65; |
到这个xml中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <invitations>
<user>
<name>paco</name>
82</amigos>
29</amigos>
6</amigos>
</user>
<user>
<name>jose</name>
43</amigos>
<tuyos>32</tuyos>
<mios>79</mios>
</amigos>
11</amigos>
</user>
<user>
<name>luis</name>
65</amigos>
</user> |
我希望我可以帮助某人
这是我编写的用于获取XML并将其转换为PHP关联数组的函数。一个警告是,id当前不处理属性或c数据。尽管它将通过将重复的XML Tag放在以该标签命名的数组中来处理相同级别的重复XML Tag。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
| <?php
$xml_req1 = <<<XML
<?xml version="1.0"?>
<Vastera:CustomerValidation_RequestInfo
xmlns:Vastera="http://ndc-ah-prd.am.mot.com:10653/MotVastera_CustomerValidation/MC000078/Docs/">
<PartnerID>5550000100-003</PartnerID>
<PartnerType>PTNR_INTER_CONSIGNEE</PartnerType>
<OperatingUnit>100</OperatingUnit>
<Status>ACTIVE</Status>
<CustomerSeqNumber>111</CustomerSeqNumber>
<CustomerName>Greg Co</CustomerName>
<Address1>123 Any Ln</Address1>
<Address2>?</Address2>
<Address3>?</Address3>
<Address4>?</Address4>
<Address5>?</Address5>
<City>Someplace</City>
<PostalCode>603021</PostalCode>
<State>CA</State>
<CountryCode>US</CountryCode>
<TaxReference>222</TaxReference>
<PartyRelated>Y</PartyRelated>
<BusinessUnit>GSBU</BusinessUnit>
<Region>GSRGN</Region>
<LocationName>DBA Mac Head Computing</LocationName>
<LoadOnly>N</LoadOnly>
<VSTM>333</VSTM>
<MilitaryCustomerFlag>Y</MilitaryCustomerFlag>
<USFederalGovernmentCustomer>Y</USFederalGovernmentCustomer>
<Non-USGovernmentCustomer>Y</Non-USGovernmentCustomer>
<Vastera:EPCIActivity>
<EPCIActivityNuclearCode>NUCLEAR</EPCIActivityNuclearCode>
<EPCIActivityNuclearValue>N</EPCIActivityNuclearValue>
<EPCIActivityNuclearApproveDate>2011-05-16:07:19:37</EPCIActivityNuclearApproveDate>
<EPCIActivityNuclearExpireDate>2056-12-31:12:00:00</EPCIActivityNuclearExpireDate>
<EPCIActivityNuclearCountry>US</EPCIActivityNuclearCountry>
<EPCIActivityChemBioCode>CHEM_BIO</EPCIActivityChemBioCode>
<EPCIActivityChemBioValue>N</EPCIActivityChemBioValue>
<EPCIActivityChemBioApproveDate>2011-05-16:07:19:37</EPCIActivityChemBioApproveDate>
<EPCIActivityChemBioExpireDate>2056-12-31:12:00:00</EPCIActivityChemBioExpireDate>
<EPCIActivityChemBioCountry>US</EPCIActivityChemBioCountry>
<EPCIActivityMissileCode>MISSILE</EPCIActivityMissileCode>
<EPCIActivityMissileValue>N</EPCIActivityMissileValue>
<EPCIActivityMissileApproveDate>2011-05-16:07:19:37</EPCIActivityMissileApproveDate>
<EPCIActivityMissileExpireDate>2056-12-31:12:00:00</EPCIActivityMissileExpireDate>
<EPCIActivityMissileCountry>US</EPCIActivityMissileCountry>
</Vastera:EPCIActivity>
<SourceSystem>GSB2BSS</SourceSystem>
<CreatedDate>2011-05-16:07:18:55</CreatedDate>
<CreatedBy>c18530</CreatedBy>
<LastModifiedDate>2011-05-16:07:18:55</LastModifiedDate>
<LastModifiedBy>c18530</LastModifiedBy>
<ContactName>Greg,"Da Man" Skluacek</ContactName>
<ContactTitle>Head Honcho</ContactTitle>
<ContactPhone>555-555-5555</ContactPhone>
<ContactFax>666-666-6666</ContactFax>
<ContactEmail>gskluzacek@gregco.com</ContactEmail>
<ContactWeb>www.gregco.com</ContactWeb>
</Vastera:CustomerValidation_RequestInfo>
XML;
$xml_req2 = <<<XML
<?xml version="1.0"?>
<order>
<orderNumber>123</orderNumber>
<customerAddress>
<type>Ship To</type>
<name>Bob McFly</name>
123 Lincoln St</addr1>
<city>Chicago</city>
<state>IL</state>
<zip>60001</zip>
</customerAddress>
<customerAddress>
<type>Bill To</type>
<name>McFly Products Inc.</name>
P.O. Box 6695</addr1>
<city>New York</city>
<state>NY</state>
<zip>99081-6695</zip>
</customerAddress>
<item>
<line>1</line>
<part>123001A</part>
<qty>5</qty>
<price>10.25</price>
</item>
<item>
<line>2</line>
<part>456002B</part>
<qty>3</qty>
<price>20.50</price>
</item>
<item>
<line>3</line>
<part>789003C</part>
<qty>1</qty>
<price>41.00</price>
</item>
<orderSubTotal>133.25</orderSubTotal>
<tax>6.66</tax>
<shipping>10.00</shipping>
<orderTotal>149.91</orderTotal>
</order>
XML;
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->loadXML($xml_req1);
$arr = xml_to_arr($doc->documentElement);
print"
----
";
print_r($arr);
print"
----
";
$doc2 = new DOMDocument();
$doc2->preserveWhiteSpace = false;
$doc2->loadXML($xml_req2);
$arr2 = xml_to_arr($doc2->documentElement);
print"
----
";
print_r($arr2);
print"
----
";
exit;
function xml_to_arr($curr_node) {
$val_array = array();
$typ_array = array();
foreach($curr_node->childNodes as $node) {
if ($node->nodeType == XML_ELEMENT_NODE) {
$val = xml_to_arr($node);
if (array_key_exists($node->tagName, $val_array)) {
if (!is_array($val_array[$node->tagName]) || $type_array[$node->tagName] == 'hash') {
$existing_val = $val_array[$node->tagName];
unset($val_array[$node->tagName]);
$val_array[$node->tagName][0] = $existing_val;
$type_array[$node->tagName] = 'array';
}
$val_array[$node->tagName][] = $val;
} else {
$val_array[$node->tagName] = $val;
if (is_array($val)) {
$type_array[$node->tagName] = 'hash';
}
} // end if array key exists
} // end if elment node
}// end for each
if (count($val_array) == 0) {
return $curr_node->nodeValue;
} else {
return $val_array;
}
} // end function xml to arr
?> |
示例输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| ----
Array
(
[PartnerID] => 5550000100-003
[PartnerType] => PTNR_INTER_CONSIGNEE
[OperatingUnit] => 100
[Status] => ACTIVE
[CustomerSeqNumber] => 111
[CustomerName] => Greg Co
[Address1] => 123 Any Ln
[Address2] => ?
[Address3] => ?
[Address4] => ?
[Address5] => ?
[City] => Somplace
[PostalCode] => 60123
[State] => CA
[CountryCode] => US
[TaxReference] => 222
[PartyRelated] => Y
[BusinessUnit] => GSBU
[Region] => GSRGN
[LocationName] => DBA Mac Head Computing
[LoadOnly] => N
[VSTM] => 333
[MilitaryCustomerFlag] => Y
[USFederalGovernmentCustomer] => Y
[Non-USGovernmentCustomer] => Y
[Vastera:EPCIActivity] => Array
(
[EPCIActivityNuclearCode] => NUCLEAR
[EPCIActivityNuclearValue] => N
[EPCIActivityNuclearApproveDate] => 2011-05-16:07:19:37
[EPCIActivityNuclearExpireDate] => 2056-12-31:12:00:00
[EPCIActivityNuclearCountry] => US
[EPCIActivityChemBioCode] => CHEM_BIO
[EPCIActivityChemBioValue] => N
[EPCIActivityChemBioApproveDate] => 2011-05-16:07:19:37
[EPCIActivityChemBioExpireDate] => 2056-12-31:12:00:00
[EPCIActivityChemBioCountry] => US
[EPCIActivityMissileCode] => MISSILE
[EPCIActivityMissileValue] => N
[EPCIActivityMissileApproveDate] => 2011-05-16:07:19:37
[EPCIActivityMissileExpireDate] => 2056-12-31:12:00:00
[EPCIActivityMissileCountry] => US
)
[SourceSystem] => GSB2BSS
[CreatedDate] => 2011-05-16:07:18:55
[CreatedBy] => c18530
[LastModifiedDate] => 2011-05-16:07:18:55
[LastModifiedBy] => c18530
[ContactName] => Greg,"Da Man" Skluacek
[ContactTitle] => Head Honcho
[ContactPhone] => 555-555-5555
[ContactFax] => 666-666-6666
[ContactEmail] => gskluzacek@gregco.com
[ContactWeb] => www.gregco.com
)
----
Array
(
[orderNumber] => 123
[customerAddress] => Array
(
[0] => Array
(
[type] => Ship To
[name] => Bob McFly
[addr1] => 123 Lincoln St
[city] => Chicago
[state] => IL
[zip] => 60001
)
[1] => Array
(
[type] => Bill To
[name] => McFly Products Inc.
[addr1] => P.O. Box 6695
[city] => New York
[state] => NY
[zip] => 99081-6695
)
)
[item] => Array
(
[0] => Array
(
[line] => 1
[part] => 123001A
[qty] => 5
[price] => 10.25
)
[1] => Array
(
[line] => 2
[part] => 456002B
[qty] => 3
[price] => 20.50
)
[2] => Array
(
[line] => 3
[part] => 789003C
[qty] => 1
[price] => 41.00
)
)
[orderSubTotal] => 133.25
[tax] => 6.66
[shipping] => 10.00
[orderTotal] => 149.91
)
-------- |
听起来像SimpleXML的工作。
我建议使用稍微不同的XML结构。
并想知道为什么需要从数组转换-> XML并返回。如果您可以像所说的那样修改数组结构,为什么不只生成XML?如果已经存在采用该数组配置的某些代码,只需对其进行修改以接受XML。然后,您就有1种数据格式/输入类型,并且根本不需要转换。
1 2 3 4 5 6 7 8 9 10
| <items>
<item id="1"/>
<item id="2"/>
<item id="3">
<subitems>
<item id="3.1"/>
<item id="3.2" isawesome="true"/>
</subitems>
</item>
</items> |
通常尝试Zend_Config和Zend Framework。
我想这将是一个两步过程:将数组转换为Zend_Config,将Zend_Config转换为XML。
您是否看到过PEAR包XML_Serializer?
pear_php_XML_Serializer
根据这里的答案,我制作了github repo https://github.com/jmarceli/array2xml
也许不是Internet上最漂亮的仓库,但是代码似乎运行良好。
这是可能使用的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| // Based on: http://stackoverflow.com/questions/99350/passing-php-associative-arrays-to-and-from-xml
class ArrayToXML {
private $version;
private $encoding;
/*
* Construct ArrayToXML object with selected version and encoding
*
* for available values check XmlWriter docs http://www.php.net/manual/en/function.xmlwriter-start-document.php
* @param string $xml_version XML Version, default 1.0
* @param string $xml_encoding XML Encoding, default UTF-8
*/
public function __construct($xmlVersion = '1.0', $xmlEncoding = 'UTF-8') {
$this->version = $xmlVersion;
$this->encoding = $xmlEncoding;
}
/**
* Build an XML Data Set
*
* @param array $data Associative Array containing values to be parsed into an XML Data Set(s)
* @param string $startElement Root Opening Tag, default data
* @return string XML String containig values
* @return mixed Boolean false on failure, string XML result on success
*/
public function buildXML($data, $startElement = 'data'){
if(!is_array($data)){
$err = 'Invalid variable type supplied, expected array not found on line '.__LINE__." in Class:".__CLASS__." Method:".__METHOD__;
trigger_error($err);
//if($this->_debug) echo $err;
return false; //return false error occurred
}
$xml = new XmlWriter();
$xml->openMemory();
$xml->startDocument($this->version, $this->encoding);
$xml->startElement($startElement);
$this->writeEl($xml, $data);
$xml->endElement();//write end element
//returns the XML results
return $xml->outputMemory(true);
}
/**
* Write keys in $data prefixed with @ as XML attributes, if $data is an array.
* When an @ prefixed key is found, a '%' key is expected to indicate the element itself,
* and '#' prefixed key indicates CDATA content
*
* @param object $xml XMLWriter Object
* @param array $data with attributes filtered out
*/
protected function writeAttr(XMLWriter $xml, $data) {
if(is_array($data)) {
$nonAttributes = array();
foreach($data as $key => $val) {
//handle an attribute with elements
if($key[0] == '@') {
$xml->writeAttribute(substr($key, 1), $val);
} else if($key[0] == '%') {
if(is_array($val)) $nonAttributes = $val;
else $xml->text($val);
} elseif($key[0] == '#') {
if(is_array($val)) $nonAttributes = $val;
else {
$xml->startElement(substr($key, 1));
$xml->writeCData($val);
$xml->endElement();
}
}
//ignore normal elements
else $nonAttributes[$key] = $val;
}
return $nonAttributes;
}
else return $data;
}
/**
* Write XML as per Associative Array
*
* @param object $xml XMLWriter Object
* @param array $data Associative Data Array
*/
protected function writeEl(XMLWriter $xml, $data) {
foreach($data as $key => $value) {
if(is_array($value) && !$this->isAssoc($value)) { //numeric array
foreach($value as $itemValue){
if(is_array($itemValue)) {
$xml->startElement($key);
$itemValue = $this->writeAttr($xml, $itemValue);
$this->writeEl($xml, $itemValue);
$xml->endElement();
} else {
$itemValue = $this->writeAttr($xml, $itemValue);
$xml->writeElement($key,"$itemValue");
}
}
} else if(is_array($value)) { //associative array
$xml->startElement($key);
$value = $this->writeAttr($xml, $value);
$this->writeEl($xml, $value);
$xml->endElement();
} else { //scalar
$value = $this->writeAttr($xml, $value);
$xml->writeElement($key,"$value");
}
}
}
/*
* Check if array is associative with string based keys
* FROM: http://stackoverflow.com/questions/173400/php-arrays-a-good-way-to-check-if-an-array-is-associative-or-sequential/4254008#4254008
*
* @param array $array Array to check
*/
protected function isAssoc($array) {
return (bool)count(array_filter(array_keys($array), 'is_string'));
}
} |
之后,只需使用ArrayToXML类。例:
1 2
| $xml = new ArrayToXML();
print $xml->buildXML($input); |
这建立在安格尔·洛佩斯(AngelLópez)的答案上。添加了对属性的支持。如果元素具有属性,请在它们前面加上@,并以空字符串作为键引用实际元素的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| /**
* Build an XML Data Set
*
* @param array $data Associative Array containing values to be parsed into an XML Data Set(s)
* @param string $startElement Root Opening Tag, default fx_request
* @param string $xml_version XML Version, default 1.0
* @param string $xml_encoding XML Encoding, default UTF-8
* @return string XML String containig values
* @return mixed Boolean false on failure, string XML result on success
*/
function arrayToXML($data, $startElement = 'fx_request', $xml_version = '1.0', $xml_encoding = 'UTF-8'){
if(!is_array($data)){
$err = 'Invalid variable type supplied, expected array not found on line '.__LINE__." in Class:".__CLASS__." Method:".__METHOD__;
trigger_error($err);
//if($this->_debug) echo $err;
return false; //return false error occurred
}
$xml = new XmlWriter();
$xml->openMemory();
$xml->startDocument($xml_version, $xml_encoding);
$xml->startElement($startElement);
/**
* Write keys in $data prefixed with @ as XML attributes, if $data is an array. When an @ prefixed key is found, a '' key is expected to indicate the element itself.
* @param object $xml XMLWriter Object
* @param array $data with attributes filtered out
*/
function writeAttr(XMLWriter $xml, $data) {
if(is_array($data)) {
$nonAttributes = array();
foreach($data as $key => $val) {
//handle an attribute with elements
if($key[0] == '@') {
$xml->writeAttribute(substr($key, 1), $val);
} else if($key == '') {
if(is_array($val)) $nonAttributes = $val;
else $xml->text("$val");
}
//ignore normal elements
else $nonAttributes[$key] = $val;
}
return $nonAttributes;
}
else return $data;
}
/**
* Write XML as per Associative Array
* @param object $xml XMLWriter Object
* @param array $data Associative Data Array
*/
function writeEl(XMLWriter $xml, $data) {
foreach($data as $key => $value) {
if(is_array($value) && isset($value[0])) { //numeric array
foreach($value as $itemValue){
if(is_array($itemValue)) {
$xml->startElement($key);
$itemValue = writeAttr($xml, $itemValue);
writeEl($xml, $itemValue);
$xml->endElement();
} else {
$itemValue = writeAttr($xml, $itemValue);
$xml->writeElement($key,"$itemValue");
}
}
} else if(is_array($value)) { //associative array
$xml->startElement($key);
$value = writeAttr($xml, $value);
writeEl($xml, $value);
$xml->endElement();
} else { //scalar
$value = writeAttr($xml, $value);
$xml->writeElement($key,"$value");
}
}
}
writeEl($xml, $data);
$xml->endElement();//write end element
//returns the XML results
return $xml->outputMemory(true);
} |
所以您可以将其转换为:
1 2 3 4 5 6 7 8 9 10 11 12 13
| $mArray["invitations"]["user"][0]["@name"] ="paco";
$mArray["invitations"]["user"][0][""]["amigos"][0] = 82;
$mArray["invitations"]["user"][0][""]["amigos"][1] = 29;
$mArray["invitations"]["user"][0][""]["amigos"][2] = 6;
$mArray["invitations"]["user"][1]["@name"] ="jose";
$mArray["invitations"]["user"][1][""]["amigos"][0] = 43;
$mArray["invitations"]["user"][1][""]["amigos"][1]["tuyos"] = 32;
$mArray["invitations"]["user"][1][""]["amigos"][1]["mios"] = 79;
$mArray["invitations"]["user"][1][""]["amigos"][2] = 11;
$mArray["invitations"]["user"][2]["@name"] ="luis";
$mArray["invitations"]["user"][2][""]["amigos"][0] = 65; |
到这个xml中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <invitations>
<user name="paco">
82</amigos>
29</amigos>
6</amigos>
</user>
<user name="jose">
43</amigos>
<tuyos>32</tuyos>
<mios>79</mios>
</amigos>
11</amigos>
</user>
<user name="luis">
65</amigos>
</user>
</invitations> |
谢谢安格尔。
我同意这是PHP文档下降的一个领域,但是对我来说,我一直将SimpleXML与xml2Array函数之类的东西混合使用。在诸如print_r之类的转储功能的帮助下,从simpleXML获得的Xml并不难导航。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| /**
* Write XML as per Associative Array
* @param object $xml XMLWriter Object
* @param array $data Associative Data Array
*/
function writeXmlRecursive(XMLWriter $xml, $data){
foreach($data as $key => $value){
if (is_array($value) && isset($value[0])){
$xml->startElement($key);
foreach($value as $itemValue){
if(is_array($itemValue)){
writeXmlRecursive($xml, $itemValue);
}
else
{
$xml->writeElement($key, $itemValue."");
}
}
$xml->endElement();
}else if(is_array($value)){
$xml->startElement($key);
writeXmlRecursive($xml, $value);
$xml->endElement();
continue;
}
if (!is_array($value)){
$xml->writeElement($key, $value."");
}
}
} |
这是最终版本,可以让我从4个嵌套级别的数组中获得所需的东西
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| <items>
<item>
<id_site>59332</id_site>
<id>33</id>
<wyn>196429985</wyn>
<tombid>23</tombid>
<tombcode>196429985</tombcode>
<religion></religion>
<lastname>lastname</lastname>
<firstname>name</firstname>
<patronymicname>patronymicname</patronymicname>
<sex>1</sex>
<birthday>2</birthday>
<birthmonth>4</birthmonth>
<birthyear>1946</birthyear>
<deathday>13</deathday>
<deathmonth>5</deathmonth>
<deathyear>2006</deathyear>
<s_comments></s_comments>
<graveyard>17446</graveyard>
<latitude></latitude>
<longitude></longitude>
<images>
<image>
<siteId>52225</siteId>
<fileId>62</fileId>
[cc lang="php"]0</prefix>
<path>path</path>
</image>
<image>
<siteId>52226</siteId>
<fileId>63</fileId>
[cc lang="php"]0</prefix>
<path>path</path>
</image>
</images>
</item>
<items> |
从xml字符串获取assoc数组的最简单方法:
1 2 3
| <?
$data_array = (array) simplexml_load_string($xml_string);
?> |
下面的类使用simplexml来实现相同的功能,您只需要遍历数组并调用ximplexml的addchild。
http://snipplr.com/view.php?codeview&id=3491
|