Solved

Iterate through XML with PHP

Posted on 2014-02-01
16
564 Views
Last Modified: 2014-04-07
I attached a file that shows the XML data that I am trying to iterate through so I can just display the country and the quantity for each. I have tried a few things with simpler XML and I was able to get it to work, but with the XML that is being generated in the picture attached I am not able to iterate and pull the values out that I want. So far have tried using the SimpleXML_LoadString() and when I var_dump($obj) I see nothing. As mentioned, with simpler XML I had more luck, but this XML that gets returned is a bit more complex.
Untitled-1.jpg
0
Comment
Question by:tarrigo
  • 6
  • 6
  • 3
  • +1
16 Comments
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 39826553
You do this with PHP SimpleXML.  You either have to use the namespace or mung the namespaces out of the document.  If you want to "sanitize" some of the data to remove any personal information, and you post the XML string here in the Code snippet, I'll be glad to show you the code that will do it.
0
 

Author Comment

by:tarrigo
ID: 39826556
Well, I attached an image in the first post that shows what you get when you just put the url that has the parameters to pull from the XML web service. It shows all the structure.
0
 
LVL 43

Expert Comment

by:Chris Stanyon
ID: 39826562
Like I said in your previous question - we need the data - a JPG just doesn't do it!
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:tarrigo
ID: 39826574
Here is what the url brings back in a browser. I have sanatized it a little.

<?xml version="1.0" encoding="utf-8"?>
<DataSet xmlns="http://XMLSearch.mysite.com/XMLSearch">
  <xs:schema id="InventorySearch" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-

msdata">
    <xs:element name="InventorySearch" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="Inventory">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="CompanyName" type="xs:string" minOccurs="0" />
                <xs:element name="Contact" type="xs:string" minOccurs="0" />
                <xs:element name="Phone" type="xs:string" minOccurs="0" />
                <xs:element name="Fax" type="xs:string" minOccurs="0" />
                <xs:element name="Email" type="xs:string" minOccurs="0" />
                <xs:element name="Address1" type="xs:string" minOccurs="0" />
                <xs:element name="Address2" type="xs:string" minOccurs="0" />
                <xs:element name="City" type="xs:string" minOccurs="0" />
                <xs:element name="State" type="xs:string" minOccurs="0" />
                <xs:element name="PostalCode" type="xs:string" minOccurs="0" />
                <xs:element name="CountryName" type="xs:string" minOccurs="0" />
                <xs:element name="PartNumber" type="xs:string" minOccurs="0" />
                <xs:element name="Quantity" type="xs:int" minOccurs="0" />
                <xs:element name="LastUpdated" type="xs:dateTime" minOccurs="0" />
                <xs:element name="Mfg" type="xs:string" minOccurs="0" />
                <xs:element name="DateCode" type="xs:string" minOccurs="0" />
                <xs:element name="Price" type="xs:string" minOccurs="0" />
                <xs:element name="Comment" type="xs:string" minOccurs="0" />
                <xs:element name="IsStock" type="xs:int" minOccurs="0" />
                <xs:element name="IsPreferredVendor" type="xs:boolean" minOccurs="0" />
                <xs:element name="CompanyID" type="xs:int" minOccurs="0" />
                <xs:element name="InventoryID" type="xs:long" 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">
    <InventorySearch xmlns="">
      <Inventory diffgr:id="Inventory1" msdata:rowOrder="0">
        <CompanyName>Test Technologies</CompanyName>
        <Contact>Sales</Contact>
        <Phone>555-555-5555</Phone>
        <Fax>555-555-5555</Fax>
        <Email>test@test.net</Email>
        <Address1>3434 Test Street</Address1>
        <Address2 />
        <City>Montreal</City>
        <State>QC</State>
        <PostalCode>H3R 2E4</PostalCode>
        <CountryName>Canada</CountryName>
        <PartNumber>LM122</PartNumber>
        <Quantity>1000</Quantity>
        <LastUpdated>2014-01-28T11:17:48.44-05:00</LastUpdated>
        <Mfg>NSC-DIES </Mfg>
        <DateCode />
        <Price>0</Price>
        <Comment>DIES of LM122                           </Comment>
        <IsStock>1</IsStock>
        <IsPreferredVendor>false</IsPreferredVendor>
        <CompanyID>2444448</CompanyID>
        <InventoryID>544544</InventoryID>
      </Inventory>
      <Inventory diffgr:id="Inventory2" msdata:rowOrder="1">
        <CompanyName>Tony Tech</CompanyName>
        <Contact>Tina</Contact>
        <Phone>555-555-5555</Phone>
        <Fax>555-555-5555</Fax>
        <Email>hettttr2@kj.cn</Email>
        <Address1>Plaza ,FuTian District Shenzhen.CN</Address1>
        <Address2 />
        <City>Shenzhen</City>
        <State>Guangdong</State>
        <PostalCode />
        <CountryName>China</CountryName>
        <PartNumber>LM122</PartNumber>
        <Quantity>7500</Quantity>
        <LastUpdated>2014-01-28T22:15:31.673-05:00</LastUpdated>
        <Mfg>NSC</Mfg>
        <DateCode>06+</DateCode>
        <Price />
        <Comment />
        <IsStock>0</IsStock>
        <IsPreferredVendor>false</IsPreferredVendor>
        <CompanyID>35012</CompanyID>
        <InventoryID>7044782424</InventoryID>
      </Inventory>
      <Inventory diffgr:id="Inventory3" msdata:rowOrder="2">
        <CompanyName>Electronics Tech</CompanyName>
        <Contact>Test Industry</Contact>
        <Phone>555-555-5555</Phone>
        <Fax>555-555-5555</Fax>
        <Email>hed@thecompany.com</Email>
        <Address1>Rm 9D, Block C, Huaqiang Garden, Fuhong Rd, Futian District</Address1>
        <Address2 />
        <City>Shenzhen</City>
        <State>Guangdong</State>
        <PostalCode>518031</PostalCode>
        <CountryName>China</CountryName>
        <PartNumber>LM122</PartNumber>
        <Quantity>7500</Quantity>
        <LastUpdated>2014-01-24T00:45:06.923-05:00</LastUpdated>
        <Mfg>NSC</Mfg>
        <DateCode>06+</DateCode>
        <Price />
        <Comment />
        <IsStock>0</IsStock>
        <IsPreferredVendor>false</IsPreferredVendor>
        <CompanyID>33367</CompanyID>
        <InventoryID>5367774166</InventoryID>
      </Inventory>
	</InventorySearch>
  </diffgr:diffgram>
</DataSet>

Open in new window

0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 39826575
The difference between posting a picture of the XML document and the actual XML document is the same as having a waiter bring you a picture of a milkshake instead of delivering the real thing.  Please take a moment to learn about the SSCCE.  It's almost always guaranteed to get you a perfect answer very, very quickly!

Or to put it another way, I'll be glad to help you, but I draw the line at having to create my own test data by retyping your XML document!
0
 

Author Comment

by:tarrigo
ID: 39826577
I certainly did not want you to type the data. I did not know how much information you needed. I apologize.
0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 39826578
:-)

Great, thanks for posting that.  I'll see if I can give you a code sample.
0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 39826614
For some reason this is not working as expected.  I'll try a workaround.
http://php.net/manual/en/simplexmlelement.getnamespaces.php
0
 

Author Comment

by:tarrigo
ID: 39826711
Yeah I recognize this is a tough one to parse. It seems the simpleXML comes back with:

object(SimpleXMLElement)#1 (0) { }
0
 
LVL 109

Accepted Solution

by:
Ray Paseur earned 500 total points
ID: 39826725
This has a bit of a "hack" feel to it, but it is reasonably generalized and will get the information you need.  Note the function at line 128.  Moving parts start at line 173.

Please see http://www.laprbass.com/RAY_temp_tarrigo.php

<?php // RAY_temp_tarrigo.php
error_reporting(E_ALL);
echo '<pre>';

// SEE http://www.experts-exchange.com/Web_Development/Web_Services/Q_28354023.html

// THE TEST DATA
$xml = <<<EOD
<?xml version="1.0" encoding="utf-8"?>
<DataSet xmlns="http://XMLSearch.mysite.com/XMLSearch">
  <xs:schema id="InventorySearch" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="InventorySearch" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="Inventory">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="CompanyName" type="xs:string" minOccurs="0" />
                <xs:element name="Contact" type="xs:string" minOccurs="0" />
                <xs:element name="Phone" type="xs:string" minOccurs="0" />
                <xs:element name="Fax" type="xs:string" minOccurs="0" />
                <xs:element name="Email" type="xs:string" minOccurs="0" />
                <xs:element name="Address1" type="xs:string" minOccurs="0" />
                <xs:element name="Address2" type="xs:string" minOccurs="0" />
                <xs:element name="City" type="xs:string" minOccurs="0" />
                <xs:element name="State" type="xs:string" minOccurs="0" />
                <xs:element name="PostalCode" type="xs:string" minOccurs="0" />
                <xs:element name="CountryName" type="xs:string" minOccurs="0" />
                <xs:element name="PartNumber" type="xs:string" minOccurs="0" />
                <xs:element name="Quantity" type="xs:int" minOccurs="0" />
                <xs:element name="LastUpdated" type="xs:dateTime" minOccurs="0" />
                <xs:element name="Mfg" type="xs:string" minOccurs="0" />
                <xs:element name="DateCode" type="xs:string" minOccurs="0" />
                <xs:element name="Price" type="xs:string" minOccurs="0" />
                <xs:element name="Comment" type="xs:string" minOccurs="0" />
                <xs:element name="IsStock" type="xs:int" minOccurs="0" />
                <xs:element name="IsPreferredVendor" type="xs:boolean" minOccurs="0" />
                <xs:element name="CompanyID" type="xs:int" minOccurs="0" />
                <xs:element name="InventoryID" type="xs:long" 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">
    <InventorySearch xmlns="">
      <Inventory diffgr:id="Inventory1" msdata:rowOrder="0">
        <CompanyName>Test Technologies</CompanyName>
        <Contact>Sales</Contact>
        <Phone>555-555-5555</Phone>
        <Fax>555-555-5555</Fax>
        <Email>test@test.net</Email>
        <Address1>3434 Test Street</Address1>
        <Address2 />
        <City>Montreal</City>
        <State>QC</State>
        <PostalCode>H3R 2E4</PostalCode>
        <CountryName>Canada</CountryName>
        <PartNumber>LM122</PartNumber>
        <Quantity>1000</Quantity>
        <LastUpdated>2014-01-28T11:17:48.44-05:00</LastUpdated>
        <Mfg>NSC-DIES </Mfg>
        <DateCode />
        <Price>0</Price>
        <Comment>DIES of LM122                           </Comment>
        <IsStock>1</IsStock>
        <IsPreferredVendor>false</IsPreferredVendor>
        <CompanyID>2444448</CompanyID>
        <InventoryID>544544</InventoryID>
      </Inventory>
      <Inventory diffgr:id="Inventory2" msdata:rowOrder="1">
        <CompanyName>Tony Tech</CompanyName>
        <Contact>Tina</Contact>
        <Phone>555-555-5555</Phone>
        <Fax>555-555-5555</Fax>
        <Email>hettttr2@kj.cn</Email>
        <Address1>Plaza ,FuTian District Shenzhen.CN</Address1>
        <Address2 />
        <City>Shenzhen</City>
        <State>Guangdong</State>
        <PostalCode />
        <CountryName>China</CountryName>
        <PartNumber>LM122</PartNumber>
        <Quantity>7500</Quantity>
        <LastUpdated>2014-01-28T22:15:31.673-05:00</LastUpdated>
        <Mfg>NSC</Mfg>
        <DateCode>06+</DateCode>
        <Price />
        <Comment />
        <IsStock>0</IsStock>
        <IsPreferredVendor>false</IsPreferredVendor>
        <CompanyID>35012</CompanyID>
        <InventoryID>7044782424</InventoryID>
      </Inventory>
      <Inventory diffgr:id="Inventory3" msdata:rowOrder="2">
        <CompanyName>Electronics Tech</CompanyName>
        <Contact>Test Industry</Contact>
        <Phone>555-555-5555</Phone>
        <Fax>555-555-5555</Fax>
        <Email>hed@thecompany.com</Email>
        <Address1>Rm 9D, Block C, Huaqiang Garden, Fuhong Rd, Futian District</Address1>
        <Address2 />
        <City>Shenzhen</City>
        <State>Guangdong</State>
        <PostalCode>518031</PostalCode>
        <CountryName>China</CountryName>
        <PartNumber>LM122</PartNumber>
        <Quantity>7500</Quantity>
        <LastUpdated>2014-01-24T00:45:06.923-05:00</LastUpdated>
        <Mfg>NSC</Mfg>
        <DateCode>06+</DateCode>
        <Price />
        <Comment />
        <IsStock>0</IsStock>
        <IsPreferredVendor>false</IsPreferredVendor>
        <CompanyID>33367</CompanyID>
        <InventoryID>5367774166</InventoryID>
      </Inventory>
	</InventorySearch>
  </diffgr:diffgram>
</DataSet>
EOD;


// FUNCTION TO MUNG THE XML SO WE DO NOT HAVE TO DEAL WITH NAMESPACE
function mungXML($xml)
{
    // A REGULAR EXPRESSION TO FIND THE NAMESPACE PREFIX
    $rgx
    = '#'             // REGEX DELIMITER
    . '\<{1}'         // ONE ESCAPED LEFT WICKET
    . '/{1}'          // ONE SLASH
    . '('             // CAPTURE GROUP
    . '.*?'           // ANYTHING OR NOTHING
    . ')'             // END CAPTURE GROUP
    . ':{1}'          // ONE COLON
    . '#'             // REGED DELIMITER
    ;
    preg_match_all($rgx, $xml, $nss);

    // CHANGE ns: INTO ns_
    $nsm = array_unique($nss[1]);
    foreach ($nsm as $key)
    {
        // A REGULAR EXPRESSION TO MUNG THE XML
        $rgx
        = '#'               // REGEX DELIMITER
        . '('               // GROUP PATTERN 1
        . '\<'              // LOCATE A LEFT WICKET
        . '/?'              // MAYBE FOLLOWED BY A SLASH
        . preg_quote($key)  // THE NAMESPACE
        . ')'               // END GROUP PATTERN
        . '('               // GROUP PATTERN 2
        . ':{1}'            // A COLON (EXACTLY ONE)
        . ')'               // END GROUP PATTERN
        . '#'               // REGEX DELIMITER
        ;
        // INSERT THE UNDERSCORE INTO THE TAG NAME
        $rep
        = '$1'          // BACKREFERENCE TO GROUP 1
        . '_'           // LITERAL UNDERSCORE IN PLACE OF GROUP 2
        ;
        // PERFORM THE REPLACEMENT
        $xml =  preg_replace($rgx, $rep, $xml);
    }
    return $xml;
}


// MUNG THE XML
$new = mungxml($xml);

// USE THE MUNGED TEST DATA AND MAKE AN OBJECT
$obj = SimpleXML_Load_String($new);

// ACTIVATE THIS TO SHOW WHAT WE GOT
// var_dump($obj);

// USE AN ITERATOR TO FIND PARTS OF THE OBJECT
foreach ($obj->diffgr_diffgram->InventorySearch->Inventory as $inventory)
{
    $n = $inventory->CompanyName;
    $c = $inventory->City;
    $t = $inventory->Contact;
    echo PHP_EOL . "REACH OUT TO <b>$t</b> AT COMPANY <b>$n</b> IN CITY <b>$c</b>";
}

Open in new window

HTH, and best regards, ~Ray
0
 

Author Closing Comment

by:tarrigo
ID: 39826752
That actually looks like it will work. I was able to get the data I needed out and I have to say I am truly appreciative of your help. This will allow me to move forward. I tried very hard to figure it out, but time was running out. So I turned here for help. I am humbled by your knowledge. Your help is again much appreciated. I will pay it forward.
0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 39826787
Thanks for the points and for your kind words, and thanks for using EE.  All the best, ~Ray
0
 
LVL 43

Expert Comment

by:Chris Stanyon
ID: 39826789
No need to hack it:

$xml = file_get_contents('data.xml');
$data = new SimpleXMLElement($xml);

$inventorySearch = $data->children('urn:schemas-microsoft-com:xml-diffgram-v1')->children()->InventorySearch;

foreach ($inventorySearch->Inventory as $inventory):
	var_dump($inventory);
endforeach;

Open in new window

0
 

Author Comment

by:tarrigo
ID: 39826799
I must say that works as well. I have already closed the question unfortunately. I appreciate you still responding even though I am not sure how to give you points after closing it. You guys definitely know your PHP. I hope to someday get to be as good. All of what I see just gives me more to research as I see how things work.
0
 
LVL 43

Expert Comment

by:Chris Stanyon
ID: 39826804
No worries on the points - just figured there had to be a proper way of doing it, and I always enjoy a challenge :)
0
 

Expert Comment

by:shart68
ID: 39982976
I was just wondering if I could ask you a question in relation to the topic discussed above?
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
The Confluence of Individual Knowledge and the Collective Intelligence At this writing (summer 2013) the term API (http://dictionary.reference.com/browse/API?s=t) has made its way into the popular lexicon of the English language.  A few years ago, …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question