Xml to php classes

simplexml_load_string

Получает правильно сформированную XML-строку и возвращает ее как объект.

Список параметров

Правильно сформированная XML-строка

Вы можете использовать этот необязательный параметр для того, чтобы функция simplexml_load_string() возвращала объект указанного класса. Этот класс должен расширять класс SimpleXMLElement .

Начиная с PHP 5.1.0 и Libxml 2.6.0, вы также можете использовать параметр options чтобы указать дополнительные параметры Libxml.

Префикс пространства имен или URI.

TRUE если ns является префиксом, и FALSE если URI; по умолчанию равен FALSE .

Возвращаемые значения

Возвращает объект ( object ) класса SimpleXMLElement со свойствами, содержащими данные, которые хранятся внутри XML-документа или FALSE в случае возникновения ошибки.

Ошибки

Генерирует сообщение об ошибке уровня E_WARNING для каждой ошибки, найденной в XML-данных.

Используйте функцию libxml_use_internal_errors() для того, чтобы подавить все ошибки XML, и функцию libxml_get_errors() для прохода по ним впоследствии.

Примеры

Пример #1 Интерпретация XML-строки

$xml = simplexml_load_string ( $string );

Результат выполнения данного примера:

SimpleXMLElement Object ( [title] => Что 40? [from] => Джо [to] => Джейн [body] => Я знаю, что это - ответ. В чем заключается вопрос? )

Здесь вы можете использовать $xml->body и проч.

Смотрите также

  • simplexml_load_file() — Интерпретирует XML-файл в объект
  • SimpleXMLElement::__construct() — Создание нового SimpleXMLElement объекта
  • Работа с ошибками XML
  • libxml_use_internal_errors() — Отключение ошибок libxml и передача полномочий по выборке и обработке информации об ошибках пользователю
  • Базовое использование SimpleXML

Источник

Php xml to php object class

So now I have an array named $results_list with sub arrays organized in $key/$value pairs, but the arrays themselves aren’t named. Solution 1: Here is a minimal working example deserializing the XML to a single instance with an of instances.

Create PHP Class or Object from XML Document

I’m working with XML documents returned by an API. The XML returns a list of products, with attributes for each project such as inventory, item number, name, price, etc.

I can loop through all of the XML tables creating lists of all the products with the appropriate fields displayed. The problem is, I need to be able to define certain products and their variables.

How can I create classes, or arrays from the XML products, but only for certain ones? For example, there may be 40 products returned, but I may only need 3 of them. The array or class must contain all the relevant information for the product.

Here’s a link to an example of the raw XML returned by the API

   14249Cleaning Deposit0.0000000.0000
14251Utility Knife2.9900900.0000

So using the second product in the above code as an example, I’d like a PHP function that will create either a class, or an array like this:

$utility_knife ( "ChargeDescID" => "14251", "dcPrice" => "2.99", "dcTax1Rate" => "9", "dcTax2Rate" => "0", "dcInStock" => "0", ) 

How can I pull out specific diffgr tables and format them into named arrays or classes, ignoring the tables I don’t need? How do I get the contents of a table while ignoring the other tables?

Edit to include what I’ve attempted:

I’ve already been able to pull them into an array using loadXML() and domxpath as follows:

$dom = new DOMDocument; $dom->loadXML($result); $xpath = new DOMXPath($dom); $el = $xpath->query('//Table'); #loop through results foreach($el as $units) < $ChargeDescID = $xpath->query('ChargeDescID', $units)->item(0)->nodeValue; $sChgDesc = $xpath->query('sChgDesc', $units)->item(0)->nodeValue; $dcPrice = $xpath->query('dcPrice', $units)->item(0)->nodeValue; $dcTax1Rate = $xpath->query('dcTax1Rate', $units)->item(0)->nodeValue; $dcTax2Rate = $xpath->query('dcTax2Rate', $units)->item(0)->nodeValue; $dcInStock = $xpath->query('dcInStock', $units)->item(0)->nodeValue; #create oragnized array for results $iterate_list = array("ChargeDescID"=>$ChargeDescID,"sChgDesc"=>$sChgDesc, "dcPrice"=>$dcPrice, "dcTax1Rate"=>$dcTax1Rate, "dcTax2Rate"=>$dcTax2Rate, "dcInStock"=>$dcInStock); #create/append array of array $results_list[] = $iterate_list; > 

So now I have an array named $results_list with sub arrays organized in $key/$value pairs, but the arrays themselves aren’t named. I can print out the results in an organized fashion as so:

 foreach($results_list as $key => $value) < echo "Charge Description ID: " . $results_list[$key]["ChargeDescID"] . "
" . "Item Description: " . $results_list[$key]["sChgDesc"] . "
" . "Item Price: " . $results_list[$key]["dcPrice"] . "
" . "Tax rate 1: " . $results_list[$key]["dcTax1Rate"] . "
" . "tax rate 2: " . $results_list[$key]["dcTax2Rate"] . "
" . "In Stock: " . $results_list[$key]["dcInStock"] . "
" ; >

EDIT: This solution I proposed below worked. I’m currently using it, but I’m open to more elegant solutions. Preferably one that selects the node directly without the need of conditional logic. ThW proposed something that may work. I’m waiting for clarification from him.

The problem is that I can’t figure out how to get specific products . I know I can use the array index, but the index may change from one pull to the next. I think I need some sort of function that says something similar to:

foreach($results_list as $key => $value) < if ( $results_list[$key]["sChgDesc"] == "Utility Knife" ) < $utility_knife = array( "sChgDesc" =>$results_list[$key]["sChgDesc"], "dcPrice" => $results_list[$key]["dcPrice"], "dcTax1Rate" => $results_list[$key]["dcTax1Rate"], "dcInStock" => $results_list[$key]["dcInStock"], ); 

and then write out the if statements for each product I need within the array.Is that about right?

I’ve tried wrapping my head around how to do this so many times now that I’m starting to confuse myself. I wasn’t sure if I could call an if statement on one of the sub- array values and then loop back through the rest of the values in that particular sub array if the value exists.

The criteria of what needs to be picked out is that I have to be able to identify which product I’m choosing. So it could be dependent on the ChargeDescID, or the sChgDesc, but not really anything else. I then need to make sure the other relevant fields are populated.

You’re already using XPath, but it can do a lot more. DOMXpath::query() is limited, too. Use DOMXpath::evaluate() — it can return scalar values.

$ChargeDescID = $xpath->query('ChargeDescID', $units)->item(0)->nodeValue; 
$ChargeDescID = $xpath->evaluate('string(ChargeDescID)', $units); 

XPath can contain complex conditions. Let’s say you want to fetch the Table element nodes with the diffgr:id attribute Table1 :

$xpath->registerNamespace('diffgr', 'urn:schemas-microsoft-com:xml-diffgram-v1'); $el = $xpath->evaluate('//Table[@diffgr:id="Table1"]'); 

XPath does not have a default namespace so if you want to address nodes in a different namespace then the empty namespace ( xmlns=»» ) you need to register a prefix for it. This can be the same prefix like in the document or a different one.

On the other side you can fetch nodes by name or more generic. * represents any element node.

$dom = new DOMDocument(); $dom->loadXml($xml); $xpath = new DOMXPath($dom); $xpath->registerNamespace('diffgr', 'urn:schemas-microsoft-com:xml-diffgram-v1'); $el = $xpath->evaluate('//Table[@diffgr:id="Table1"]'); $results_list = []; foreach ($el as $units) < $iterate_list = []; foreach ($xpath->evaluate('*', $units) as $valueNode) < $iterate_list[$valueNode->localName] = $valueNode->nodeValue; > $results_list[] = $iterate_list; > var_dump($results_list); 
array(1) < [0]=>array(6) < ["ChargeDescID"]=>string(5) "14249" ["sChgDesc"]=> string(16) "Cleaning Deposit" ["dcPrice"]=> string(6) "0.0000" ["dcTax1Rate"]=> string(1) "0" ["dcTax2Rate"]=> string(1) "0" ["dcInStock"]=> string(6) "0.0000" > > 

You already tried something this:

 $xml = simplexml_load_file('file_xml.xml'); print '
'; print_r($xml); 

The print_r used only for debugging

Transforming an XSD template to an XML instance in PHP, The benefit of that method is in flexibility, simply edit the foreach loop to modify your special structure.

How to deserialize XML to an object that contains an array collection in php Symfony

I have a php object that I want to deserialize into.

 class POS < /** * @ORM\OneToMany(targetEntity="POS_Source", mappedBy="POS", orphanRemoval=true) * @Groups("Include") */ private $Source; public function __construct() < $this->Source = new ArrayCollection(); > /** * @return ArrayCollection|OTA_POS_Source[] */ public function getSource(): ArrayCollection < return $this->Source; > public function addSource(POS_Source $source): self < if (!$this->Source->contains($source)) < $this->Source[] = $source; $source->setPOS($this); > return $this; > public function removeSource(POS_Source $source): self < if ($this->Source->contains($source)) < $this->Source->removeElement($source); // set the owning side to null (unless already changed) if ($source->getPOS() === $this) < $source->setPOS(null); > > return $this; > 
 $classMetadataFactory = new ClassMetadataFactory( new AnnotationLoader(new AnnotationReader()) ); $metadataAwareNameConverter = new MetadataAwareNameConverter($classMetadataFactory); $normalizers = [new DateTimeNormalizer(), new ArrayDenormalizer(), new PropertyNormalizer(), new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter)]; $encoders = [new XmlEncoder(), new JsonEncoder()]; $serializer = new Serializer($normalizers, $encoders); $encoder = new XmlEncoder(); $output[] = $encoder->decode($data,'xml'); dump($output); /** * @var OTA_POS $pos */ $pos = $serializer->deserialize($data,POS::class,'xml'); $posSourceArray = $serializer->deserialize($pos->getSource(),'App\POS_Source[]','xml'); dump($posSourceArray); 

It gives me the POS object but rather than a collection of POS_Source objects it gives be an array below.

 POS array:4 [▶] 1 => array:1 [▶] 2 => array:1 [▶] 3 => array:1 [▶] 4 => array:1 [▶] ] > 

How can I make this work to populate the object tree all the way to the bottom. When I serialize from object structure to XML it works great.

Here is a minimal working example deserializing the XML to a single POS instance with an ArrayCollection of POS_Source instances. I threw away all normalizers etc. not essential for deserializing this particular XML.

use Doctrine\Common\Collections\ArrayCollection; use Symfony\Component\Serializer\Encoder\XmlEncoder; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; class POS < // . just as in the question . >/** * Minimal implementation of POS_Source for purposes of this deserialization example. */ class POS_Source < private $RequestorID; public function setPOS(POS $POS) < >public function getRequestorID() < return $this->RequestorID; > public function setRequestorID($RequestorID) < $this->RequestorID = $RequestorID; > > $data = ' '; $normalizers = [ new ArrayDenormalizer(), new ObjectNormalizer(null, null, null, new ReflectionExtractor()) ]; $encoders = [new XmlEncoder()]; $serializer = new Serializer($normalizers, $encoders); $pos = $serializer->deserialize($data,POS::class,'xml'); dump($pos); 
POS POS_Source 11 "@ID" => "T921" "CompanyName" => array:3 [ "@Code" => "CP" "@CodeContext" => "123T" "#" => "" ] ] > 1 => POS_Source 1 "@ID" => 34778 "#" => "" ] > 2 => POS_Source 9 "@ID" => "ZF" "#" => "" ] > 3 => POS_Source 17 "@ID" => "mabaan" "#" => "" ] > ] > > 

This is a partial answer not a solution.

So it looks like deserialize doesn't support embedded php objects and that you have create a custom deserialize method.

I'm still working the solution but short answer is you have to iterate through the normalized array and then attempt to match property names. I'm trying to find a method to query the object for only those properties included in the serialization group doc block annotation.

When deserializing objects containing other objects, you have to provide the ObjectNormalizer with a type extractor which determines type of the nested objects .

use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; // . $normalizers = [ new DateTimeNormalizer(), new ArrayDenormalizer(), new PropertyNormalizer(), new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter, null, new ReflectionExtractor()), // added type extractor as fourth argument ]; 

See also the official documentation on this topic.

Xml - PHP Parse stdclass object, I get the following output (var_dump) from an API call. I need to obtain the data elements or put them into an array so I can use them as individual …

How PHP Soap Client converts XML to a stdClass Object

PHPs native soap client returns the XML response as a std class object. Can someone tell me how it is done, there has to be some inbuilt parse function to do that rt?

And it uses libxml to parse the SOAP request: SourceCode

Send XML with php via post, I know there are any number of similar questions to this on SO, but I've tried messing around with all the solutions and haven't seemed to be able to …

Источник

Читайте также:  Тег TD
Оцените статью