0

I've been trying to figure out how to parse this xml string.

I get an empty object returned from simplexml_load_string.

Any idea on how to proceed is greatly appreciated.

SimpleXMLElement Object
(
)

This is the XML being received from an ASP.net server. Attempting to parse with PHP.

<?xml version="1.0" encoding="utf-8"?>
<DataSet>
  <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="Table">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="MadeBy" minOccurs="0">
                  <xs:simpleType>
                    <xs:restriction base="xs:string">
                      <xs:maxLength value="50" />
                    </xs:restriction>
                  </xs:simpleType>
                </xs:element>
                <xs:element name="Note" minOccurs="0">
                  <xs:simpleType>
                    <xs:restriction base="xs:string">
                      <xs:maxLength value="255" />
                    </xs:restriction>
                  </xs:simpleType>
                </xs:element>
                <xs:element name="DateMade" type="xs:dateTime" 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">
    <NewDataSet>
      <Table diffgr:id="Table1" msdata:rowOrder="0">
        <MadeBy>admin</MadeBy>
        <Note>Test note v2, now with added characters for a longer note!</Note>
        <DateMade>2018-04-02T12:45:18.503-04:00</DateMade>
      </Table>
      <Table diffgr:id="Table2" msdata:rowOrder="1">
        <MadeBy>admin</MadeBy>
        <Note>Test application with a test note</Note>
        <DateMade>2018-04-02T12:44:56.05-04:00</DateMade>
      </Table>
    </NewDataSet>
  </diffgr:diffgram>
</DataSet>

I thought I should get something back other than an empty object.

jhpratt
  • 6,841
  • 16
  • 40
  • 50
Ken Stone
  • 1
  • 3
  • If you don't show us your code, it's hard to help. – ascripter Apr 03 '18 at 01:05
  • This was the key that got it working for me: ` $notes_obj = simplexml_load_string($notes);` ` $children = $notes_obj->children('urn:schemas-microsoft-com:xml-diffgram-v1')->children(); ` – Ken Stone Apr 04 '18 at 02:32

3 Answers3

1

As pointed out - print_r() is the wrong thing to check what you have loaded into a SimpleXMLElement. If you ever want to see the content, then use ->asXML() which will print out the XML of any elements.

The following code shows how you can access the data in the XML you have, I use simplexml_load_string, but loaf_file gives the same results...

$xml = simplexml_load_string($data);
print_r($xml);
echo $xml->asXML();
$data = $xml->children("diffgr", true)[0];
foreach ( $data->children("", true)->NewDataSet->Table as $table )  {
    echo "MadeBy=".$table->MadeBy.PHP_EOL;
}

I use the children() method as there are elements in a namespace and this allows you to fetch these easily. children("diffgr", true) fetches the elements in with the namespace prefix diffgr, later I use "" to fetch the elements in the default namespace.

This outputs...

SimpleXMLElement Object
(
)
<?xml version="1.0" encoding="utf-8"?>
<DataSet>
  <xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="NewDataSet">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">

         ...

        <DateMade>2018-04-02T12:44:56.05-04:00</DateMade>
      </Table>
    </NewDataSet>
  </diffgr:diffgram>
</DataSet>
MadeBy=admin
MadeBy=admin
Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
0

SimpleXMLElement instances may sometimes appear empty to functions like print_r() or var_dump() even if the XML was properly loaded, since the class is just an interface between PHP and LibXML.

I have tested your XML code and it loads properly, all methods of SimpleXMLElement can be used appropriately.

For example

var_dump($e = simplexml_load_string(...));
var_dump($e->getName());

prints

object(SimpleXMLElement)#1 (0) {
}
string(7) "DataSet"

This thread has some good ideas about how to detect and handle LibXML errors in PHP with the standard interfaces: simplexml error handling php

Cobra_Fast
  • 15,671
  • 8
  • 57
  • 102
0

Two things lead to my success. print_r not showing what I thought it was and the children method. I kept overlooking that method in the php.net documentation.

 $notes_obj = simplexml_load_string($notes);
 $children = $notes_obj->children('urn:schemas-microsoft-com:xml-diffgram-v1')->children();

And using

var_export($notes_obj, true)
JDB
  • 25,172
  • 5
  • 72
  • 123
Ken Stone
  • 1
  • 3
  • The best way to "thank" other SO users is to vote on their answers. If you found an answer especially helpful, please vote on their answer instead of trying to respond to them directly. It's how the gamification works. ;) – JDB May 24 '19 at 19:14