简体   繁体   中英

PHP XML - Extract repeating element and child elements to array

I using the built in PHP SOAP function and CURL to send an request and get a response from an .Net ASMX web service .

Currently I´m receiving the response as an XML, but need some help with extracting information from the XML as the data I need is nested deep in the XML. For example extract only what I need and convert it to an array in order to send it directly to an database.

The XML starts as follows:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
  <GetViewBidResponse xmlns="http://domain.com/SolutionWebService">
     <GetViewBidResult>
        <message>OK</message>
        <table>
           <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">
              <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="Bidrod" msdata:UseCurrentLocale="true">
                 <xs:complexType>
                    <xs:choice minOccurs="0" maxOccurs="unbounded">
                       <xs:element name="Bid">
                          <xs:complexType>
                             <xs:sequence>
                                <xs:element name="rows" msprop:ColumnId="1" type="xs:string" minOccurs="0"/>
                                <xs:element name="Queue" msprop:ColumnId="2" type="xs:string" minOccurs="0"/>
                                <xs:element name="Running" msprop:ColumnId="3" type="xs:string" minOccurs="0"/>
                                <xs:element name="New" msprop:ColumnId="4" type="xs:string" minOccurs="0"/>
                                <xs:element name="Working" msprop:ColumnId="5" type="xs:string" minOccurs="0"/>
                                <xs:element name="Done" msprop:ColumnId="6" type="xs:string" minOccurs="0"/>
                                <xs:element name="Agree" msprop:ColumnId="7" type="xs:string" minOccurs="0"/>
                                <xs:element name="Canceled" msprop:ColumnId="8" type="xs:string" minOccurs="0"/>
                                <xs:element name="Hold" msprop:ColumnId="9" type="xs:string" minOccurs="0"/>
                                <xs:element name="Test" msprop:ColumnId="10" type="xs:string" minOccurs="0"/>
                                <xs:element name="All" msprop:ColumnId="11" type="xs:string" minOccurs="0"/>
                             </xs:sequence>
                          </xs:complexType>
                       </xs:element>
                    </xs:choice>
                 </xs:complexType>
              </xs:element>
           </xs:schema>
           <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
              <DocumentElement xmlns="">
                 <Bid diffgr:id="Bid1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
                    <rows>1</rodun>
                    <Queue>Testqueue1</Queue>
                    <Running>1</Running>
                    <New>2</New>
                    <Working>7</Working>
                    <Done>4802</Lokið>
                    <Agree>1</Agree>
                    <Canceled>87</Canceled>
                    <Hold>3</Hold>
                    <Test>0</Test>
                    <All>4902</All>
                 </Bid>
                 <Bid diffgr:id="Bid2" msdata:rowOrder="1" diffgr:hasChanges="inserted">
                    <rows>1</rodun>
                    <Queue>Testqueue2</Queue>
                    <Running>23</Running>
                    <New>q2</New>
                    <Working>27</Working>
                    <Done>48</Lokið>
                    <Agree>11</Agree>
                    <Canceled>827</Canceled>
                    <Hold>31</Hold>
                    <Test>10</Test>
                    <All>402</All>
                 </Bid>
                 <Bid diffgr:id="Bid3" msdata:rowOrder="2" diffgr:hasChanges="inserted">
...shortened, this continues from "diffgr:id="Bid1" to "diffgr:id="Bid97"...

What I would like to do is extract all child elements under each element <Bid diffgr:id="Bid1" (that starts after the DocumentElement element). It would be great to end with an array that has only the following info:

[DocumentElement] => Array ( // Optional
[Bid] => Array (          // Optional
  [0] => Array (
    [rows] => 1
    [Queue] => Testqueue1
    [Running] => 1
    [New] => 2
    [Working] => 7
    [Done] => 4802
    [Agree] => 1
    [Canceled] => 87
    [Hold] => 3
    [Test] => 0
    [All] => 4902 )
  [1] => Array (
    [rows] => 1
    [Queue] => Testqueue2
    [Running] => 1
    [New] => 4
    [Working] => 3
  ... and continues with all "Bid diffgr:id="BidXX" (number can reach 99) ...

If I can get help with extracting only what I need to an array, then I could manage the rest (adding them to an database).

I have been looking at xpath but with no success binding it to the correct xpath element. This is what I tried but with no luck:

$xml = simplexml_load_string($response);
$id = $xml->xpath("Bid[@id=Bid*]");  // Not sure how to use the wildcard
var_dump($id);

I have also been able to convert the whole XML to an array by using XML2ARRAY but then I still need to extract only what I need stated above.

Any help would be appreciated.

I see the advantage of the SoapClient , but want to answer the xpath-part:

$results = $xml->xpath("//Bid"); 

will select all <Bid> nodes and their children. To access those:

foreach ($results as $result) {

    echo $result->rows . "<br />";

}

This node in your XML seems to be broken, though:

<rows>1</rodun>

You should use the SoapClient class for SOAP communication. Although it is possible to implement a soap client using low level HTTP and XML handling only, I would not advice you to do this in most cases, as this can go weird if the data structures go complex.

Use the page that I've linked and the comments on it as a good starting point. Here comes another tutorial link: http://devzone.zend.com/25/php-soap-extension/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM