2008-09-26 48 views
45

Cách tốt nhất để lấy một đối tượng PHP đã cho và tuần tự hóa nó là XML là gì? Tôi đang xem simple_xml và tôi đã sử dụng nó để phân tích cú pháp XML thành các đối tượng, nhưng nó không rõ ràng đối với tôi cách nó hoạt động theo cách khác.Đối tượng PHP dưới dạng tài liệu XML

Trả lời

37

hãy xem gói PE2's XML_Serializer. Tôi đã sử dụng nó với kết quả khá tốt. Bạn có thể nạp nó các mảng, các đối tượng vv và nó sẽ biến chúng thành XML. Nó cũng có một loạt các tùy chọn như chọn tên của nút gốc, vv

Nên làm các trick

+3

Tôi đang cố gắng sử dụng gói này ngay hôm nay (4 năm sau khi phản hồi này) trên php 5.3.13 và tôi nhận được các lỗi tiêu chuẩn nghiêm ngặt trên XML_Serializer và các phụ thuộc của nó. Biết về bất kỳ lựa chọn thay thế nào khác? – djule5

+1

Cảnh báo, thư viện có phụ thuộc khủng khiếp! – clankill3r

5

Sử dụng một hàm dom để làm điều đó: http://www.php.net/manual/en/function.dom-import-simplexml.php

nhập đối tượng SimpleXML và sau đó lưu. Liên kết trên chứa một ví dụ. :)

Tóm lại:

<?php 
$array = array('hello' => 'world', 'good' => 'morning'); 

$xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><foo />"); 
foreach ($array as $k=>$v) { 
    $xml->addChild($k, $v); 
} 
?> 
+1

Tôi không nghĩ rằng đây trả lời câu hỏi, tôi khá chắc chắn rằng anh ấy muốn làm một cái gì đó giống như mảng chuyển đổi ("foo" => "bar") vào " thanh" (không chính xác nhưng bạn có ý tưởng) – davr

+0

Bạn có thể điền đơn giản obj ect? – Till

+0

Nhưng anh ta không hỏi làm thế nào để chuyển đổi các đối tượng simplexml thành xml, anh ta muốn các đối tượng XML đơn giản. Trừ khi tôi hiểu lầm, tôi không thấy một cách dễ dàng để chuyển cấu trúc dữ liệu PHP tùy ý (đối tượng, mảng, chuỗi vv) thành đối tượng simplexml (và do đó thành chuỗi XML) – davr

-1

Vâng, trong khi một chút bẩn, bạn có thể luôn luôn chạy một vòng trên các thuộc tính của đối tượng ...

$_xml = ''; 
foreach($obj as $key => $val){ 
    $_xml .= '<' . $key . '>' . $val . '</' . $key . ">\n"; 
} 

Sử dụng fopen/fwrite/fclose bạn có thể tạo một tài liệu XML với biến số $_xml làm nội dung. Nó xấu xí, nhưng nó sẽ hoạt động.

+0

Có lỗi cú pháp nhỏ. Không có nối sau khóa $ thứ hai. –

+0

hoạt động, nhưng nếu bạn cần xử lý các đối tượng trên 1 mức độ sâu, hãy thử http://stackoverflow.com/questions/137021/php-object-as-xml-document/2194774#2194774 – philfreo

+0

Bạn đang đùa tôi? –

9

không hoàn toàn là câu trả lời cho t ông câu hỏi ban đầu, nhưng cách tôi giải quyết vấn đề của tôi với điều này là bằng cách tuyên bố đối tượng của tôi là:

$root = '<?xml version="1.0" encoding="UTF-8"?><Activities/>'; 
$object = new simpleXMLElement($root); 

như trái ngược với:

$object = new stdClass; 

trước khi tôi bắt đầu thêm bất kỳ giá trị!

46

Tôi đồng ý với việc sử dụng XML_Serializer của PEAR, nhưng nếu bạn muốn một cái gì đó đơn giản hỗ trợ các đối tượng/mảng có thuộc tính lồng nhau, bạn có thể sử dụng nó.

class XMLSerializer { 

    // functions adopted from http://www.sean-barton.co.uk/2009/03/turning-an-array-or-object-into-xml-using-php/ 

    public static function generateValidXmlFromObj(stdClass $obj, $node_block='nodes', $node_name='node') { 
     $arr = get_object_vars($obj); 
     return self::generateValidXmlFromArray($arr, $node_block, $node_name); 
    } 

    public static function generateValidXmlFromArray($array, $node_block='nodes', $node_name='node') { 
     $xml = '<?xml version="1.0" encoding="UTF-8" ?>'; 

     $xml .= '<' . $node_block . '>'; 
     $xml .= self::generateXmlFromArray($array, $node_name); 
     $xml .= '</' . $node_block . '>'; 

     return $xml; 
    } 

    private static function generateXmlFromArray($array, $node_name) { 
     $xml = ''; 

     if (is_array($array) || is_object($array)) { 
      foreach ($array as $key=>$value) { 
       if (is_numeric($key)) { 
        $key = $node_name; 
       } 

       $xml .= '<' . $key . '>' . self::generateXmlFromArray($value, $node_name) . '</' . $key . '>'; 
      } 
     } else { 
      $xml = htmlspecialchars($array, ENT_QUOTES); 
     } 

     return $xml; 
    } 

} 
+3

đẹp, hoạt động tuyệt vời cho tôi. đặc biệt là nếu bạn không muốn bất kỳ sự phụ thuộc nào từ PEAR. – dermatthias

+0

Có thể ai đó đưa ra ví dụ về cách sử dụng này không? Thực sự đấu tranh. –

+2

@MattBoyle, tôi đã sử dụng json_decode để lấy simpleXML làm đối tượng. Hãy thử điều này với đối tượng của bạn. '$ xml_generater = new XMLSerializer; \t $ std_class = json_decode (json_encode ($ object)); \t $ xml = $ xml_generater-> generateValidXmlFromObj ($ std_class); ' – Goose

-1

Trong khi tôi đồng ý với @philfreo và lý do của anh ấy rằng bạn không nên phụ thuộc vào PEAR, giải pháp của anh ấy vẫn chưa hoàn toàn ở đó. Có những vấn đề tiềm năng khi chìa khóa có thể là một chuỗi chứa bất kỳ các ký tự sau:

  • <
  • >
  • \ s (không gian)
  • "
  • '

Bất kỳ điều nào trong số này sẽ loại bỏ định dạng, vì XML sử dụng các ký tự này trong ngữ pháp của nó.Vì vậy, không có thêm ado, đây là một giải pháp đơn giản để mà xảy ra rất có thể:

function xml_encode($var, $indent = false, $i = 0) { 
    $version = "1.0"; 
    if (!$i) { 
     $data = '<?xml version="1.0"?>' . ($indent ? "\r\n" : '') 
       . '<root vartype="' . gettype($var) . '" xml_encode_version="'. $version . '">' . ($indent ? "\r\n" : ''); 
    } 
    else { 
     $data = ''; 
    } 

    foreach ($var as $k => $v) { 
     $data .= ($indent ? str_repeat("\t", $i) : '') . '<var vartype="' .gettype($v) . '" varname="' . htmlentities($k) . '"'; 

     if($v == "") { 
      $data .= ' />'; 
     } 
     else { 
      $data .= '>'; 
      if (is_array($v)) { 
       $data .= ($indent ? "\r\n" : '') . xml_encode($v, $indent, $verbose, ($i + 1)) . ($indent ? str_repeat("\t", $i) : ''); 
      } 
      else if(is_object($v)) { 
       $data .= ($indent ? "\r\n" : '') . xml_encode(json_decode(json_encode($v), true), $indent, $verbose, ($i + 1)) . ($indent ? str_repeat("\t", $i) : ''); 
      } 
      else { 
       $data .= htmlentities($v); 
      } 

      $data .= '</var>'; 
     } 

     $data .= ($indent ? "\r\n" : ''); 
    } 

    if (!$i) { 
     $data .= '</root>'; 
    } 

    return $data; 
} 

Đây là một cách sử dụng mẫu:

// sample object 
$tests = Array(
    "stringitem" => "stringvalue", 
    "integeritem" => 1, 
    "floatitem" => 1.00, 
    "arrayitems" => Array("arrayvalue1", "arrayvalue2"), 
    "hashitems" => Array("hashkey1" => "hashkey1value", "hashkey2" => "hashkey2value"), 
    "literalnull" => null, 
    "literalbool" => json_decode(json_encode(1)) 
); 
// add an objectified version of itself as a child 
$tests['objectitem'] = json_decode(json_encode($tests), false); 

// convert and output 
echo xml_encode($tests); 

/* 
// output: 

<?xml version="1.0"?> 
<root vartype="array" xml_encode_version="1.0"> 
<var vartype="integer" varname="integeritem">1</var> 
<var vartype="string" varname="stringitem">stringvalue</var> 
<var vartype="double" varname="floatitem">1</var> 
<var vartype="array" varname="arrayitems"> 
    <var vartype="string" varname="0">arrayvalue1</var> 
    <var vartype="string" varname="1">arrayvalue2</var> 
</var> 
<var vartype="array" varname="hashitems"> 
    <var vartype="string" varname="hashkey1">hashkey1value</var> 
    <var vartype="string" varname="hashkey2">hashkey2value</var> 
</var> 
<var vartype="NULL" varname="literalnull" /> 
<var vartype="integer" varname="literalbool">1</var> 
<var vartype="object" varname="objectitem"> 
    <var vartype="string" varname="stringitem">stringvalue</var> 
    <var vartype="integer" varname="integeritem">1</var> 
    <var vartype="integer" varname="floatitem">1</var> 
    <var vartype="array" varname="arrayitems"> 
     <var vartype="string" varname="0">arrayvalue1</var> 
     <var vartype="string" varname="1">arrayvalue2</var> 
    </var> 
    <var vartype="array" varname="hashitems"> 
     <var vartype="string" varname="hashkey1">hashkey1value</var> 
     <var vartype="string" varname="hashkey2">hashkey2value</var> 
    </var> 
    <var vartype="NULL" varname="literalnull" /> 
    <var vartype="integer" varname="literalbool">1</var> 
</var> 
</root> 

*/ 

Chú ý rằng tên chính được lưu trữ trong các thuộc tính varname (html được mã hóa) và thậm chí cả loại được lưu trữ, do đó có thể loại bỏ tuần tự đối xứng. Chỉ có một vấn đề với điều này: nó sẽ không serialize lớp, chỉ có đối tượng instantiated, mà sẽ không bao gồm các phương thức lớp. Điều này chỉ có chức năng để chuyển "dữ liệu" qua lại.

Tôi hy vọng điều này sẽ giúp ai đó, mặc dù điều này đã được trả lời từ lâu.

1

hãy nhìn vào phiên bản của tôi

class XMLSerializer { 

    /** 
    * 
    * The most advanced method of serialization. 
    * 
    * @param mixed $obj => can be an objectm, an array or string. may contain unlimited number of subobjects and subarrays 
    * @param string $wrapper => main wrapper for the xml 
    * @param array (key=>value) $replacements => an array with variable and object name replacements 
    * @param boolean $add_header => whether to add header to the xml string 
    * @param array (key=>value) $header_params => array with additional xml tag params 
    * @param string $node_name => tag name in case of numeric array key 
    */ 
    public static function generateValidXmlFromMixiedObj($obj, $wrapper = null, $replacements=array(), $add_header = true, $header_params=array(), $node_name = 'node') 
    { 
     $xml = ''; 
     if($add_header) 
      $xml .= self::generateHeader($header_params); 
     if($wrapper!=null) $xml .= '<' . $wrapper . '>'; 
     if(is_object($obj)) 
     { 
      $node_block = strtolower(get_class($obj)); 
      if(isset($replacements[$node_block])) $node_block = $replacements[$node_block]; 
      $xml .= '<' . $node_block . '>'; 
      $vars = get_object_vars($obj); 
      if(!empty($vars)) 
      { 
       foreach($vars as $var_id => $var) 
       { 
        if(isset($replacements[$var_id])) $var_id = $replacements[$var_id]; 
        $xml .= '<' . $var_id . '>'; 
        $xml .= self::generateValidXmlFromMixiedObj($var, null, $replacements, false, null, $node_name); 
        $xml .= '</' . $var_id . '>'; 
       } 
      } 
      $xml .= '</' . $node_block . '>'; 
     } 
     else if(is_array($obj)) 
     { 
      foreach($obj as $var_id => $var) 
      { 
       if(!is_object($var)) 
       { 
        if (is_numeric($var_id)) 
         $var_id = $node_name; 
        if(isset($replacements[$var_id])) $var_id = $replacements[$var_id]; 
        $xml .= '<' . $var_id . '>';  
       } 
       $xml .= self::generateValidXmlFromMixiedObj($var, null, $replacements, false, null, $node_name); 
       if(!is_object($var)) 
        $xml .= '</' . $var_id . '>'; 
      } 
     } 
     else 
     { 
      $xml .= htmlspecialchars($obj, ENT_QUOTES); 
     } 

     if($wrapper!=null) $xml .= '</' . $wrapper . '>'; 

     return $xml; 
    } 

    /** 
    * 
    * xml header generator 
    * @param array $params 
    */ 
    public static function generateHeader($params = array()) 
    { 
     $basic_params = array('version' => '1.0', 'encoding' => 'UTF-8'); 
     if(!empty($params)) 
      $basic_params = array_merge($basic_params,$params); 

     $header = '<?xml'; 
     foreach($basic_params as $k=>$v) 
     { 
      $header .= ' '.$k.'='.$v; 
     } 
     $header .= ' ?>'; 
     return $header; 
    }  
} 
+1

Bạn có thể so sánh và đối chiếu điều này với các tùy chọn được cung cấp trước đó không? – trex005

+0

Giải pháp tuyệt vời !!! Nó hoạt động tốt với mảng sâu của objetcs và mảng. Cảm ơn bạn. –

0

Tôi biết đây là một câu hỏi cũ, nhưng gần đây tôi đã phải tạo ra cấu trúc XML phức tạp.

Cách tiếp cận của tôi chứa các nguyên tắc OOP nâng cao. Ý tưởng là để tuần tự hóa đối tượng cha mẹ có chứa nhiều trẻ em và con.

Các nút lấy tên từ tên lớp nhưng bạn có thể ghi đè tên lớp bằng thông số đầu tiên khi tạo đối tượng để tuần tự hóa.

Bạn có thể tạo: nút đơn giản, không có nút con, EntityList và ArrayList. EntityList là một danh sách các đối tượng của cùng một lớp, nhưng một ArrayList có thể có các đối tượng khác nhau.

Mỗi đối tượng phải mở rộng lớp trừu tượng SerializeXmlAbstract để khớp với tham số đầu vào đầu tiên trong lớp: Object2xml, phương thức serialize($object, $name = NULL, $prefix = FALSE).

Theo mặc định, nếu bạn không cung cấp tham số thứ hai, nút XML gốc sẽ có tên lớp của đối tượng đã cho. Tham số thứ ba chỉ ra nếu tên nút gốc có tiền tố hay không. Tiền tố được mã hóa cứng dưới dạng thuộc tính riêng tư trong lớp Export2xml.

interface SerializeXml { 

    public function hasAttributes(); 

    public function getAttributes(); 

    public function setAttributes($attribs = array()); 

    public function getNameOwerriden(); 

    public function isNameOwerriden(); 
} 

abstract class SerializeXmlAbstract implements SerializeXml { 

    protected $attributes; 
    protected $nameOwerriden; 

    function __construct($name = NULL) { 
     $this->nameOwerriden = $name; 
    } 

    public function getAttributes() { 
     return $this->attributes; 
    } 

    public function getNameOwerriden() { 
     return $this->nameOwerriden; 
    } 

    public function setAttributes($attribs = array()) { 
     $this->attributes = $attribs; 
    } 

    public function hasAttributes() { 
     return (is_array($this->attributes) && count($this->attributes) > 0) ? TRUE : FALSE; 
    } 

    public function isNameOwerriden() { 
     return $this->nameOwerriden != NULL ? TRUE : FALSE; 
    } 

} 

abstract class Entity_list extends SplObjectStorage { 

    protected $_listItemType; 

    public function __construct($type) { 
     $this->setListItemType($type); 
    } 

    private function setListItemType($param) { 
     $this->_listItemType = $param; 
    } 

    public function detach($object) { 
     if ($object instanceOf $this->_listItemType) { 
      parent::detach($object); 
     } 
    } 

    public function attach($object, $data = null) { 
     if ($object instanceOf $this->_listItemType) { 
      parent::attach($object, $data); 
     } 
    } 

} 

abstract class Array_list extends SerializeXmlAbstract { 

    protected $_listItemType; 
    protected $_items; 

    public function __construct() { 
     //$this->setListItemType($type); 
     $this->_items = new SplObjectStorage(); 
    } 

    protected function setListItemType($param) { 
     $this->_listItemType = $param; 
    } 

    public function getArray() { 
     $return = array(); 
     $this->_items->rewind(); 
     while ($this->_items->valid()) { 
      $return[] = $this->_items->current(); 
      $this->_items->next(); 
     } 
     // print_r($return); 
     return $return; 
    } 

    public function detach($object) { 
     if ($object instanceOf $this->_listItemType) { 
      if (in_array($this->_items->contains($object))) { 
       $this->_items->detach($object); 
      } 
     } 
    } 

    public function attachItem($ob) { 
     $this->_items->attach($ob); 
    } 

} 

class Object2xml { 

    public $rootPrefix = "ernm"; 
    private $addPrefix; 
    public $xml; 

    public function serialize($object, $name = NULL, $prefix = FALSE) { 
     if ($object instanceof SerializeXml) { 
      $this->xml = new DOMDocument('1.0', 'utf-8'); 
      $this->xml->appendChild($this->object2xml($object, $name, TRUE)); 
      $this->xml->formatOutput = true; 
      echo $this->xml->saveXML(); 
     } else { 
      die("Not implement SerializeXml interface"); 
     } 
    } 

    protected function object2xml(SerializeXmlAbstract $object, $nodeName = NULL, $prefix = null) { 
     $single = property_exists(get_class($object), "value"); 
     $nName = $nodeName != NULL ? $nodeName : get_class($object); 

     if ($prefix) { 
      $nName = $this->rootPrefix . ":" . $nName; 
     } 
     if ($single) { 
      $ref = $this->xml->createElement($nName); 
     } elseif (is_object($object)) { 
      if ($object->isNameOwerriden()) { 
       $nodeName = $object->getNameOwerriden(); 
      } 
      $ref = $this->xml->createElement($nName); 
      if ($object->hasAttributes()) { 
       foreach ($object->getAttributes() as $key => $value) { 
        $ref->setAttribute($key, $value); 
       } 
      } 
      foreach (get_object_vars($object) as $n => $prop) { 
       switch (gettype($prop)) { 
        case "object": 
         if ($prop instanceof SplObjectStorage) { 
          $ref->appendChild($this->handleList($n, $prop)); 
         } elseif ($prop instanceof Array_list) { 
          $node = $this->object2xml($prop); 
          foreach ($object->ResourceGroup->getArray() as $key => $value) { 
           $node->appendChild($this->object2xml($value)); 
          } 
          $ref->appendChild($node); 
         } else { 
          $ref->appendChild($this->object2xml($prop)); 
         } 
         break; 
        default : 
         if ($prop != null) { 
          $ref->appendChild($this->xml->createElement($n, $prop)); 
         } 
         break; 
       } 
      } 
     } elseif (is_array($object)) { 
      foreach ($object as $value) { 
       $ref->appendChild($this->object2xml($value)); 
      } 
     } 
     return $ref; 
    } 

    private function handleList($name, SplObjectStorage $param, $nodeName = NULL) { 
     $lst = $this->xml->createElement($nodeName == NULL ? $name : $nodeName); 
     $param->rewind(); 
     while ($param->valid()) { 
      if ($param->current() != null) { 
       $lst->appendChild($this->object2xml($param->current())); 
      } 
      $param->next(); 
     } 
     return $lst; 
    } 
} 

Đây là mã bạn cần để có thể nhận xml hợp lệ từ các đối tượng. mẫu tiếp theo tạo xml này:

<InsertMessage priority="high"> 
    <NodeSimpleValue firstAttrib="first" secondAttrib="second">simple value</NodeSimpleValue> 
    <Arrarita> 
    <Title>PHP OOP is great</Title> 
    <SequenceNumber>1</SequenceNumber> 
    <Child> 
     <FirstChild>Jimmy</FirstChild> 
    </Child> 
    <Child2> 
     <FirstChild>bird</FirstChild> 
    </Child2> 
    </Arrarita> 
    <ThirdChild> 
    <NodeWithChilds> 
     <FirstChild>John</FirstChild> 
     <ThirdChild>James</ThirdChild> 
    </NodeWithChilds> 
    <NodeWithChilds> 
     <FirstChild>DomDocument</FirstChild> 
     <SecondChild>SplObjectStorage</SecondChild> 
    </NodeWithChilds> 
    </ThirdChild> 
</InsertMessage> 

Lớp học cần thiết cho xml này là:

class NodeWithArrayList extends Array_list { 

    public $Title; 
    public $SequenceNumber; 

    public function __construct($name = NULL) { 
     echo $name; 
     parent::__construct($name); 
    } 

} 

class EntityListNode extends Entity_list { 

    public function __construct($name = NULL) { 
     parent::__construct($name); 
    } 

} 

class NodeWithChilds extends SerializeXmlAbstract { 

    public $FirstChild; 
    public $SecondChild; 
    public $ThirdChild; 

    public function __construct($name = NULL) { 
     parent::__construct($name); 
    } 

} 

class NodeSimpleValue extends SerializeXmlAbstract { 

    protected $value; 

    public function getValue() { 
     return $this->value; 
    } 

    public function setValue($value) { 
     $this->value = $value; 
    } 

    public function __construct($name = NULL) { 
     parent::__construct($name); 
    } 
} 

Và cuối cùng mã mà nhanh chóng đối tượng là:

$firstChild = new NodeSimpleValue("firstChild"); 
$firstChild->setValue("simple value"); 
$firstChild->setAttributes(array("firstAttrib" => "first", "secondAttrib" => "second")); 

$secondChild = new NodeWithArrayList("Arrarita");  
$secondChild->Title = "PHP OOP is great"; 
$secondChild->SequenceNumber = 1; 


$firstListItem = new NodeWithChilds(); 
$firstListItem->FirstChild = "John"; 
$firstListItem->ThirdChild = "James"; 

$firstArrayItem = new NodeWithChilds("Child"); 
$firstArrayItem->FirstChild = "Jimmy"; 

$SecondArrayItem = new NodeWithChilds("Child2"); 
$SecondArrayItem->FirstChild = "bird"; 

$secondListItem = new NodeWithChilds(); 
$secondListItem->FirstChild = "DomDocument"; 
$secondListItem->SecondChild = "SplObjectStorage"; 


$secondChild->attachItem($firstArrayItem); 
$secondChild->attachItem($SecondArrayItem); 

$list = new EntityListNode("NodeWithChilds"); 
$list->attach($firstListItem); 
$list->attach($secondListItem); 



$message = New NodeWithChilds("InsertMessage"); 
$message->setAttributes(array("priority" => "high")); 
$message->FirstChild = $firstChild; 
$message->SecondChild = $secondChild; 
$message->ThirdChild = $list; 


$object2xml = new Object2xml(); 
$object2xml->serialize($message, "xml", TRUE); 

Hy vọng nó sẽ giúp một ai đó.

Chúc mừng, Siniša

0

Đây là mã của tôi sử dụng cho serializing đối tượng PHP để XML "dễ hiểu" bởi Microsoft .NET XmlSerializer.Deserialize

class XMLSerializer { 

    /** 
    * Get object class name without namespace 
    * @param object $object Object to get class name from 
    * @return string Class name without namespace 
    */ 
    private static function GetClassNameWithoutNamespace($object) { 
     $class_name = get_class($object); 
     return end(explode('\\', $class_name)); 
    } 

    /** 
    * Converts object to XML compatible with .NET XmlSerializer.Deserialize 
    * @param type $object Object to serialize 
    * @param type $root_node Root node name (if null, objects class name is used) 
    * @return string XML string 
    */ 
    public static function Serialize($object, $root_node = null) { 
     $xml = '<?xml version="1.0" encoding="UTF-8" ?>'; 
     if (!$root_node) { 
      $root_node = self::GetClassNameWithoutNamespace($object); 
     } 
     $xml .= '<' . $root_node . ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">'; 
     $xml .= self::SerializeNode($object); 
     $xml .= '</' . $root_node . '>'; 
     return $xml; 
    } 

    /** 
    * Create XML node from object property 
    * @param mixed $node Object property 
    * @param string $parent_node_name Parent node name 
    * @param bool $is_array_item Is this node an item of an array? 
    * @return string XML node as string 
    * @throws Exception 
    */ 
    private static function SerializeNode($node, $parent_node_name = false, $is_array_item = false) { 
     $xml = ''; 
     if (is_object($node)) { 
      $vars = get_object_vars($node); 
     } else if (is_array($node)) { 
      $vars = $node; 
     } else { 
      throw new Exception('Coś poszło nie tak'); 
     } 

     foreach ($vars as $k => $v) { 
      if (is_object($v)) { 
       $node_name = ($parent_node_name ? $parent_node_name : self::GetClassNameWithoutNamespace($v)); 
       if (!$is_array_item) { 
        $node_name = $k; 
       } 
       $xml .= '<' . $node_name . '>'; 
       $xml .= self::SerializeNode($v); 
       $xml .= '</' . $node_name . '>'; 
      } else if (is_array($v)) { 
       $xml .= '<' . $k . '>'; 
       if (count($v) > 0) { 
        if (is_object(reset($v))) { 
         $xml .= self::SerializeNode($v, self::GetClassNameWithoutNamespace(reset($v)), true); 
        } else { 
         $xml .= self::SerializeNode($v, gettype(reset($v)), true); 
        } 
       } else { 
        $xml .= self::SerializeNode($v, false, true); 
       } 
       $xml .= '</' . $k . '>'; 
      } else { 
       $node_name = ($parent_node_name ? $parent_node_name : $k); 
       if ($v === null) { 
        continue; 
       } else { 
        $xml .= '<' . $node_name . '>'; 
        if (is_bool($v)) { 
         $xml .= $v ? 'true' : 'false'; 
        } else { 
         $xml .= htmlspecialchars($v, ENT_QUOTES); 
        } 
        $xml .= '</' . $node_name . '>'; 
       } 
      } 
     } 
     return $xml; 
    } 
} 

dụ:

class GetProductsCommandResult { 
    public $description; 
    public $Errors; 
} 

class Error { 
    public $id; 
    public $error; 
} 

$obj = new GetProductsCommandResult(); 
$obj->description = "Teścik"; 
$obj->Errors = array(); 
$obj->Errors[0] = new Error(); 
$obj->Errors[0]->id = 666; 
$obj->Errors[0]->error = "Sth"; 
$obj->Errors[1] = new Error(); 
$obj->Errors[1]->id = 666; 
$obj->Errors[1]->error = null; 


$xml = XMLSerializer::Serialize($obj); 

kết quả trong:

<?xml version="1.0" encoding="UTF-8"?> 
<GetProductsCommandResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <description>Teścik</description> 
    <Errors> 
     <Error> 
     <id>666</id> 
     <error>Sth</error> 
     </Error> 
     <Error> 
     <id>666</id> 
     </Error> 
    </Errors> 
</GetProductsCommandResult> 
Các vấn đề liên quan