Szukałem gotowej biblioteki - znalazłem kilka ale albo wolne, albo nie działają jak powinny. Postanowiłem napisać własną, niestety napotkałem problem.
O ile samo generowanie XML`a nie sprawia problemu o tyle gdy jego struktura ma być bardziej zagnieżdżona - gubię się.
Jeśli chodzi o parsowanie to kompletnie nie wiem jak podejść do problemu. Aby nie zaśmiecać forum pokażę tylko kawałki kodu:
<?php private function rpc_type($a) { if((string)$a === "true" || (string)$a === "false")return "boolean"; if($a == (string)(int)$a){ //if(substr($a,-2)==".0")return "double"; } if("$a" === ("".(double)$a))return "double"; if(preg_match("/^((?:(?:[1]{1}\\d{1}\\d{1}\\d{1})|(?:[2]{1}\\d{3}))(?:[0]?[1-9]|[1][012])(?:(?:[0-2]?\\d{1})|(?:[3][0,1]{1})))(?![\\d])(T)((?:(?:[0-1][0-9])|(?:[2][0-3])|(?:[0-9])):(?:[0-5][0-9])(?::[0-5][0-9])?(?:\\s?(?:am|AM|pm|PM))?)$/", $a) || preg_match("/^((?:(?:[1]{1}\\d{1}\\d{1}\\d{1})|(?:[2]{1}\\d{3}))(?:[0]?[1-9]|[1][012])(?:(?:[0-2]?\\d{1})|(?:[3][0,1]{1})))(?![\\d])(T)((?:(?:[0-1][0-9])|(?:[2][0-3])|(?:[0-9])):(?:[0-5][0-9])(?::[0-5][0-9])?(?:\\s?(?:am|AM|pm|PM))?)(\\+)((?:(?:[0-1][0-9])|(?:[2][0-3])|(?:[0-9])):(?:[0-5][0-9])(?::[0-5][0-9])?(?:\\s?(?:am|AM|pm|PM))?)$/", $a))return "dateTime.iso8601"; //Looks funny, yea? ;] Lets write better one! return "string"; } private function build_struct($struct) { //Sample array: //["foo"] => "bar" //["childrens"] => 3 //["name"] => "value" $ret = "<struct>\n"; foreach($struct as $name => $value) { $type = $this->rpc_type($value); $ret .= " <member>\n"; $ret .= " <name>$name</name>\n"; $ret .= " <value><$type>$value</$type></value>\n"; $ret .= " </member>\n"; } $ret .= "</struct>\n"; return $ret; } private function build_array($array) { //Sample array: //[0] => a //[1] => 1 //[2] => YWK= //<array> elements do not have names, use <struct> if you want names $ret = "<array>\n"; $ret .= " <data>\n"; foreach($array as $name => $value) { $type = $this->rpc_type($value); $ret .= " <value><$type>$value</$type></value>\n"; } $ret .= " </data>\n"; $ret .= "</array>\n"; return $ret; } function build_call($params) { /*Sample $params array: array(2) { ["method_name"] => "system.listMethods" ["params"]=> array(4) { ["value_0"] => "abcd" ["struct_0"]=> array(2) { ["test"] => "123" ["test2"] => "lala ;]" } ["array_0"]=> array(4) { [0] => "a" [1] => "b" [2] => "1" [3] => "2" } ["value_1"] => "19980717T14:08:55+1:00" } } */ $ret = '<?xml version="1.0" ?>'."\n"; $ret .= " <methodCall>\n"; $ret .= " <methodName>".$params["method_name"]."</methodName>\n"; $ret .= " <params>\n"; foreach($params["params"] as $param_block_name => $param_block_data) { $tmp = ""; if(stripos($param_block_name, "value_") !== false) { $type = $this->rpc_type($param_block_data); $tmp = " <value><$type>$param_block_data</$type></value>\n"; } elseif(stripos($param_block_name, "struct_") !== false) { $tmp = " <value>".$this->build_struct($param_block_data)."</value>\n"; } elseif(stripos($param_block_name, "array_") !== false) { $tmp = " <value>".$this->build_array($param_block_data)."</value>\n"; } } } $ret .= " </params>\n"; $ret .= " </methodCall>\n"; return $ret; } ?>
Wywołanie build_call z przykładową tablicą wygeneruje takie coś:
<?xml version="1.0" ?> <methodCall> <methodName>system.listMethods</methodName> <params> <param> <value><string>abcd</string></value> </param> <param> <value><struct> <member> <name>test</name> <value><int>123</int></value> </member> <member> <name>test2</name> <value><string>lala ;]</string></value> </member> </struct> </value> </param> <param> <value><array> <data> <value><string>a</string></value> <value><string>b</string></value> <value><int>1</int></value> <value><int>2</int></value> </data> </array> </value> </param> <param> <value><dateTime.iso8601>19980717T14:08:55+1:00</dateTime.iso8601></value> </param> </params> </methodCall>
Wszytko było by ok gdyby nie to, że nie mogę zagnieżdżać dalej w drzewie, tzn nie mogę zrobić takiej tablicy:
Kod
["method_name"] => "system.listMethods"
["params"]=>
array(4) {
["value_0"] => "abcd"
["struct_0"]=>
array(2) {
["test"] =>
array(2) {
["struct_0"] =>
["a"] => "b",
["b"] => "c"
}
["struct_1"] =>
["foo"] => "bar",
["ciocia"] => "ala"
}
["test2"] => "lala;]"
}
}
["params"]=>
array(4) {
["value_0"] => "abcd"
["struct_0"]=>
array(2) {
["test"] =>
array(2) {
["struct_0"] =>
["a"] => "b",
["b"] => "c"
}
["struct_1"] =>
["foo"] => "bar",
["ciocia"] => "ala"
}
["test2"] => "lala;]"
}
}
Wiem, że trzeba to jakoś parsować wywołując funkcję samą w sobie a nie zagnieżdżać fory+if = niestety nie wiem jak.
================================================================================
==========
Osobny problem: parsowanie wyniku. Ten sam problem co wcześniej - zagnieżdżenia

W odpowiedzi na zapytanie dostaje takiego XML`a:
<?xml version="1.0" encoding="UTF-8"?> <methodResponse> <params> <param><value><array><data> <value><array><data> <value><string>8BE80CE2312C1758C6BEE67374E088858630A354</string></value> <value><string>Mega.Ubuntu.Pack</string></value> <value><i8>1</i8></value> <value><i8>7150480939</i8></value> <value><i8>709541888</i8></value> <value><i8>0</i8></value> <value><i8>707788800</i8></value> <value><string>leech</string></value> <value><i8>1280158620</i8></value> <value><i8>21927</i8></value> <value><i8>558019627</i8></value> <value><i8>0</i8></value> <value><i8>1</i8></value> <value><i8>0</i8></value> <value><i4>0</i4></value> </data></array></value> <value><array><data> <value><string>CDC844A364AE2417EA204EA4840129B2298E7DD4</string></value> <value><string>ubuntu-10.04.1-desktop-i386.iso</string></value> <value><i8>1</i8></value> <value><i8>718864384</i8></value> <value><i8>158154752</i8></value> <value><i8>0</i8></value> <value><i8>155189248</i8></value> <value><string>leech</string></value> <value><i8>1282089174</i8></value> <value><i8>29825</i8></value> <value><i8>159052692</i8></value> <value><i8>18</i8></value> <value><i8>1</i8></value> <value><i8>2939379</i8></value> <value><i4>0</i4></value> </data></array></value> </data></array></value></param> </params> </methodResponse>
I kompletnie nie wiem jak do niego podejść. Dodatkowym ogranicznikiem jest dla mnie standaryzacja wyniku - chciałbym aby wygląd tablicy która zostanie zwrócona pasował do schematu z pierwszego postu.
Oczywiście schemat nie jest z góry ustalony - to jak to zrobiłem w funkcji generującej XML to jedyne co przyszło mi sensownie do głowy jeśli chodzi o rzutowanie struktury XML na tablicę wielowymiarową.
Czy ktoś dobroduszny mógłby pomóc w tym zagadnieniu?
