Autor Zpráva
quatzael
Profil
Mám k dispozici XML dokument a potřebuju data z něj dostat do proměnné typu objekt. Chtěl jsem použít funkci simplexml_load_file(), ale to XML používá vlastní jmenné prostory, takže to nefunguje..
Nevíte prosím někdo jak se to jednoduše dá udělat?

Mám taky k dispozici soubor, který se tváří jako XML schema, tak předpokládám, že by se to mělo požít na to parsování, ale vůbec nevím jak..
Keeehi
Profil
quatzael:
potřebuju data z něj dostat do proměnné typu objekt.
Instance třídy SimpleXMLElement je objekt. Pokud však rozhraní vyžaduje něco spečifičtějšího než jakýkoli objekt, tak by se hodilo nám to rozhraní ukázat. Takže kam ta data mají jít dál?
Taps
Profil
quatzael:
je mozne dat odkaz na dany xml soubor?
quatzael
Profil
Keeehi:
Nepotřebuje nic specifičtějšího. Potřebuje právě ten objekt, o kterém tady píšu, že potřebuju z toho xml dostat.

Taps:
To není veřejný dokument, nemůžu to tady jen tak dávat.. Mohl bych akorát nějak přepsat všechny názvy, aby z toho nebylo nic poznat. Ale mě jde o vysvětlení principu jak na to. Tohle nebude jedinej XML dokument, takže bych potřeboval nějak z jednodušeně vysvětlit postup jak z XML dostat objekt a případně i jak z objektu dostat XML. Co jsem zatím nastudoval, tak bych řekl, že se k tomu má použít XML schema, ale nevím vůbec jak..
Joker
Profil
quatzael:
Nechápu tenhle výrok:
Chtěl jsem použít funkci simplexml_load_file(), ale to XML používá vlastní jmenné prostory, takže to nefunguje.

Proč by to s jmennými prostory mělo nefungovat?
quatzael
Profil
Joker:
Já nevím, tak možná to je kvůli něčemu jinému, každopádně to asi není "simle" XML, když to nefunguje.
Nebo mám někde jinou chybu a mám se tu funkci simplexml_load_file() snažit nějak rozchodit?
A co to XML schema, to je tam na nic?

Ptám se tady na radu, protože nerozumím úplně tomu jak funguje XML, jestli jde o jmenný prostory nebo něco jiného proč nejde použít simplexml_load_file(), nedokážu zatím rozhodnout.


Tak tady je ta ukázka jak to XML vypadá:

<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:zaza="http://www.zaza-company.com">
   <soapenv:Header/>
   <soapenv:Body>
      <zaza:MainFunction>
         <zaza:export>
            <zaza:Process>
               <zaza:CreatedTime>2015-02-10T13:00:00+02:00</zaza:CreatedTime>
               <zaza:Payment>
                  <zaza:BeginDate>2015-03-22T00:00:00+02:00</zaza:BeginDate>
                  <zaza:Time>1000</zaza:Time>
                  <zaza:Frequency>4</zaza:Frequency>
               </zaza:Payment>
               <zaza:Person>
                  <zaza:LegalForm>LTC</zaza:LegalForm>
                  <zaza:BirthDate>1975-10-10T00:00:00+02:00</zaza:BirthDate>
                  <zaza:Address>
                     <zaza:Zip>744852</zaza:Zip>
                     <zaza:City>Bklyn</zaza:City>
                     <zaza:Country>US</zaza:Country>
                  </zaza:Address>
              </zaza:Person>
               <zaza:Property>
                 <zaza:Type>TUX</zaza:Type>
                 <zaza:Count>12</zaza:Count>
                 <zaza:Power>4</zaza:Power>
                 <zaza:Date>2013-10-01T00:00:00+02:00</zaza:Date>
                 <zaza:Others>
                     <zaza:Months>8</zaza:Months>
                 </zaza:Others> 
               </zaza:Property>
            </zaza:Process>
         </zaza:export>
      </zaza:MainFunction>
   </soapenv:Body>
</soapenv:Envelope>
juriad
Profil
quatzael:
Schéma slouží k ověření správnosti toho konkrétního XML. Některé nástroje (JAXB v javě) používají schéma pro vygenerování tříd, z nichž se později budou vytvářet objekty.

simplexml_load_file vrací instanci třídy SimpleXMLElement, což je objekt.
Pomocí jeho metod můžeš procházet celý strom XML. Jediná záludnost, která tam číhá je, že pro získání simpleType hodnoty musíš návratovou hodnotu přetypovat.

Chceš-li si na základě schématu vytvořit PHP třídy, které se později budou používat, našel jsem knihovnu, která tvrdí, že to umí.
github.com/josephspens/JAXB a příklad použití github.com/josephspens/JAXB/blob/master/test.php
Podle zdrojáků je to až pitomně jednoduché, takže většinu pokročilých věcí z definice schématu to umět nebude.
quatzael
Profil
juriad:
No tak já jsem myslel, že v PHP existuje nějaká funkce, která mi bude podle XML schema převádět XML dokumenty na objekty a naopak. Jestli ne,tak to si budu muset opravdu naprogramovat něco vlastního..


juriad:
A proč mi teda v tomhle případě nefunguje ta funkce simplexml_load_file(), když jmenné prostory jí údajně nevadí..?
juriad
Profil
Co znamená, že nefunguje?
Můžeš ukázat kus kódu, který jsi zkoušel a místo, kde začne selhávat?
quatzael
Profil
juriad:
 $xml = simplexml_load_file($_SERVER['DOCUMENT_ROOT'] . '/../xml/xml.xml') or die("Error: Cannot create object");
Napíše to: Error: Cannot create object
juriad
Profil
Ono to ale funguje, jen PHP si myslí, že výsledek simplexml_load_file je nepravdivý - je to prázdný objekt, ale rozhodně to není FALSE.
Takže konstrukce or die('...') je chybná. Nepoužívej jí, nikdy.

Zkus toto:
<?php
# načtení
$xml = simplexml_load_file('x.xml');
var_dump($xml); # vypíše prázdný objekt

# zkusíme získat body (index 1, protože před ním je header)
$body = $xml->children('soapenv', TRUE)[1];
var_dump($body); # vypíše prázdný objekt

# zkusíme získat mainFunction
$mainFunction = $body->children('zaza', TRUE)[0];
var_dump($mainFunction); # a ono to něco vypíše

# a jdeme na export
$export = $mainFunction->children('zaza', TRUE)[0];
var_dump($export); # opět funguje

# toto se zdá, že nefunguje
$mainFunction2 = $body->mainFunction;
var_dump($mainFunction2); # prázdný objekt

# ale toto funguje (teď už navigujeme pomocí jmen nikoli pořadí potomků)
$export2 = $mainFunction->export;
var_dump($export2); # to samé jako $export

Tedy ono to funguje, ale podivně.
Na debugování se ještě hodí metoda asXML, pomocí které zjistíš, zda to vrátí správný podstrom, i když jej var_dump nevypíše.
quatzael
Profil
juriad:
Co používáš za verzi PHP? Mě to Tvoje řešení hází syntaktickou chybu:
$body = $xml->children('soapenv', TRUE)[1];
Parse error: syntax error, unexpected '[' in /www/neco.php on line 81
Alphard
Profil
To bylo přidáno tuším v PHP 5.4. Updatem na aktuální verzi nic nezkazíš.
juriad
Profil
Nejnovější (5.6.6).
As of PHP 5.4 it is possible to array dereference the result of a function or method call directly. Before it was only possible using a temporary variable.
Opravit si to na starší verzi snad zvládneš sám.
quatzael
Profil
juriad:
A taky mi jde o to jak z toho celkově dostat objekt na úrovni $mainFunction. A objektem myslím úplně normální objekt, ne SimpleXMLElement objekt.
juriad
Profil
quatzael:
PHP nemá nic jako normální objekt ve standarní knihovně (na rozdíl od JavaScriptu). Pokud nechceš SimpleXMLElement, musíš ty ty třídy napsat sám a sám provést příslušnou transformaci z SimpleXMLElementu.
quatzael
Profil
Alphard:
Hmm. Já mám verzi 5.3.29. Mám to na cizím hostingu, takže asi nic updatovat nemůžu..

juriad:
Opravit si to na starší verzi snad zvládneš sám.
Opraveno.:o)

juriad:
PHP nemá nic jako normální objekt ve standarní knihovně (na rozdíl od JavaScriptu).
Jo, asi úplně stačí tohle. Teď to funguje. Je to objekt, který se vkládá jako parametr do webové služby. Teď to ale vypadá, že už je to ok, jen to řve, že mu tam chybí jedna vlastnost v tom objektu. Což je trochu divný, protože to xmlko mám od toho poskytovatele ws jako testovací..


No každopádně díky. Převod XML na objekt se zdá být jakžtakž vyřešen.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0