Asked  7 Months ago    Answers:  5   Viewed   34 times

Hello this is my first post. i'm trying to parse an xml using php, but i'm stuck with it

example of my xml :

<xml xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
     xmlns:rs='urn:schemas-microsoft-com:rowset'
     xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
   <s:ElementType name='row' content='eltOnly' rs:CommandTimeout='30'>
      <s:AttributeType name='ows_LinkTitle' rs:name='Phone Number*' rs:number='1'>
         <s:datatype dt:type='string' dt:maxLength='512' />
      </s:AttributeType>
      <s:AttributeType name='ows_GSM_x0020_PUK' rs:name='GSM PUK' rs:number='2'>
         <s:datatype dt:type='string' dt:maxLength='512' />
      </s:AttributeType>
   </s:ElementType>
</s:Schema>
<rs:data>
   <z:row ows_LinkTitle='628558621183' ows_GSM_x0020_PUK='41016732'/>
   <z:row ows_LinkTitle='628558621181' ows_GSM_x0020_PUK='21783670'/>
</rs:data>
</xml>

i'm trying to get the value from each of 'z:row' Any help is very appreciated. Thanks

i'm trying this code and it doesnt work

$xml_all = simplexml_load_string($xmlnya);

echo '<ol>';
foreach ($xml_all->xml->rs->z as $zrow)
{
 echo '<li> ows_LinkTitle: '.$zrow['ows_LinkTitle'];
 echo '</li>';
}
echo '</ol>';

 Answers

78

The snippets below assume the (fixed) XML document is a string in $xml.

SimpleXML

$xml  = simplexml_load_string($xml);
$rows = $xml->children('rs', TRUE)->data->children('z', TRUE)->row;
foreach ($rows as $row) {
    $attributes = $row->attributes();
    $link_title = (string) $attributes->ows_LinkTitle;
    $gsm_puk    = (string) $attributes->ows_GSM_x0020_PUK;
    var_dump($link_title, $gsm_puk);
}

To read: SimpleXML usage, SimpleXMLElement::children(), SimpleXMLElement::attributes().

DOM

$doc = new DOMDocument;
$doc->loadXML($xml);
$rows = $doc->getElementsByTagNameNS('#RowsetSchema', 'row');
foreach ($rows as $row) {
    $link_title = $row->getAttribute('ows_LinkTitle');
    $gsm_puk    = $row->getAttribute('ows_GSM_x0020_PUK');
    var_dump($link_title, $gsm_puk);
}

To read: DOMDocument::getElementsByTagNameNS(), DOMElement::getAttribute().

Saturday, May 29, 2021
 
nomie
answered 7 Months ago
90

Figured out the issue was with the XML feed rather than code:

XML feed was missing this line:

<r25:events xmlns:r25="http://www.collegenet.com/r25" xmlns:xl="http://www.w3.org/1999/xlink" pubdate="2010-05-19T13:58:08-04:00">

Thanks for the help though.

Saturday, May 29, 2021
 
Lloydworth
answered 7 Months ago
54

You can use an xpath query to target the node names that starts with Foto, then after getting those nodes, then just use foreach:

$xml_string = '<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:noNamespaceSchemaLocation="propiedades.xsd" generated="2015-04-28T15:16:46">
<propiedades>
<Descripcion>Excelente casa de dos pisos en condominio en la urbanización Santa Maria De Villa Club, en Carabayllo, con un AT:92m2 y un AC:113m2, cuenta con 3 iluminadas habitaciones, 3 baños, cochera, de estreno, con áreas verdes, piscina, cancha de fútbol, salones para actividades. ¡Para más información contactarse con nuestros agente!ID:   35751</Descripcion>
<Foto1>http://www.alfredograf.com/fotoprop/mini-35751%20-%201.jpg</Foto1>
<Foto2>http://www.alfredograf.com/fotoprop/mini-35751%20-%202.jpg</Foto2>
<Foto3>http://www.alfredograf.com/fotoprop/mini-35751%20-%203.jpg</Foto3>
<Foto4>http://www.alfredograf.com/fotoprop/mini-35751%20-%204.jpg</Foto4>
<Foto5>http://www.alfredograf.com/fotoprop/mini-35751%20-%205.jpg</Foto5>
<Foto6>http://www.alfredograf.com/fotoprop/mini-35751%20-%206.jpg</Foto6>
<Foto7>http://www.alfredograf.com/fotoprop/mini-35751%20-%207.jpg</Foto7>
<Foto8>http://www.alfredograf.com/fotoprop/mini-35751%20-%208.jpg</Foto8>
</propiedades>
</dataroot>';

$xml = simplexml_load_string($xml_string);
$fotos = $xml->xpath('//*[substring(name(), 1, 4) = "Foto"]');
foreach($fotos as $foto) {
    echo $foto, '<br/>';
}

Sample Output

If you don't want to use the xpath route, just use ->getName to check the node name and use normal PHP string functions to check it:

$xml = simplexml_load_string($xml_string);
foreach($xml->propiedades->children() as $element) {
    if(substr($element->getName(), 0, 4) === 'Foto') {
        echo $element, '<br/>';
    }
}

Sample Output

Saturday, May 29, 2021
 
Puneet
answered 7 Months ago
33

This was how i have eventually done it using XMLReader:

<?php

define ('XMLFILE', 'http://ws.audioscrobbler.com/2.0/artist/vasco%20rossi/images.rss');
echo "<pre>";

$items = array ();
$i = 0;

$xmlReader = new XMLReader();
$xmlReader->open(XMLFILE, null, LIBXML_NOBLANKS);

$isParserActive = false;
$simpleNodeTypes = array ("title", "description", "media:title", "link", "author", "pubDate", "guid");

while ($xmlReader->read ())
{
    $nodeType = $xmlReader->nodeType;

    // Only deal with Beginning/Ending Tags
    if ($nodeType != XMLReader::ELEMENT && $nodeType != XMLReader::END_ELEMENT) { continue; }
    else if ($xmlReader->name == "item") {
        if (($nodeType == XMLReader::END_ELEMENT) && $isParserActive) { $i++; }
        $isParserActive = ($nodeType != XMLReader::END_ELEMENT);
    }

    if (!$isParserActive || $nodeType == XMLReader::END_ELEMENT) { continue; }

    $name = $xmlReader->name;

    if (in_array ($name, $simpleNodeTypes)) {
        // Skip to the text node
        $xmlReader->read ();
        $items[$i][$name] = $xmlReader->value;
    } else if ($name == "media:thumbnail") {
        $items[$i]['media:thumbnail'] = array (
                "url" => $xmlReader->getAttribute("url"),
                "width" => $xmlReader->getAttribute("width"),
                "height" => $xmlReader->getAttribute("height"),
                "type" => $xmlReader->getAttribute("type")
        );
    } else if ($name == "media:content") {
        $items[$i]['media:content'] = array (
                "url" => $xmlReader->getAttribute("url"),
                "width" => $xmlReader->getAttribute("width"),
                "height" => $xmlReader->getAttribute("height"),
                "filesize" => $xmlReader->getAttribute("fileSize"),
                "expression" => $xmlReader->getAttribute("expression")
        );
    }
}

print_r($items);
echo "</pre>";

?>
Saturday, July 31, 2021
 
Exoon
answered 4 Months ago
41

Currently your XML is invalid since the test namespace is not declared, you can declare it like this:

<item xmlns:test="http://foo.bar">
  <test:link_id>1282570</test:link_id>
  <test:user>SLAYERTANIC</test:user>
  <title>aaa</title>
  <description>aaa</description>
</item>

Having this you can use XNamespace to qualify the XML element you want with the correct namespace:

XElement xdoc = XElement.Parse(e.Result);
XNamespace test = "http://foo.bar";
this.newsList.ItemsSource = from item in xdoc.Descendants("item")
                            select new ArticlesItem
                            {
                                LinkID = item.Element(test + "link_id").Value,
                                Title = item.Element("title").Value,
                                Description = this.Strip(item.Element("description").Value).Substring(0, 200).ToString()
                            }
Wednesday, August 25, 2021
 
OneNoOne
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share