0

I'm trying to parse a response from the Ontraport API, which is returned in an ugly XML format.

<result>
    <contact id="1" date="1424746532" dlm="1425357692" score="0.00" purl="" bulk_mail="1">
        <Group_Tag name="Contact Information">
            <field name="Company">Test.com</field>
            <field name="Email">test@test.com</field>
            <field name="Group"/>
            <field name="Specialty"/>
            <field name="User ID"/>
            <field name="Display First"/>
            <field name="Display Last"/>
        </Group_Tag>
    </contact>
</result>

Im using SimpleXML and the simplexml_load_string function. When I var_dump the response from that function I get the following output:

object(SimpleXMLElement)#1 (1) {
  ["contact"]=>
  object(SimpleXMLElement)#2 (2) {
    ["@attributes"]=>
    array(6) {
      ["id"]=>
      string(1) "1"
      ["date"]=>
      string(10) "1424746532"
      ["dlm"]=>
      string(10) "1425357692"
      ["score"]=>
      string(4) "0.00"
      ["purl"]=>
      string(0) ""
      ["bulk_mail"]=>
      string(1) "1"
    }
    ["Group_Tag"]=>
    object(SimpleXMLElement)#3 (2) {
      ["@attributes"]=>
      array(1) {
        ["name"]=>
        string(19) "Contact Information"
      }
      ["field"]=>
      array(7) {
        [0]=>
        string(8) "Test.com"
        [1]=>
        string(13) "test@test.com"
        [2]=>
        object(SimpleXMLElement)#4 (1) {
          ["@attributes"]=>
          array(1) {
            ["name"]=>
            string(5) "Group"
          }
        }
        [3]=>
        object(SimpleXMLElement)#5 (1) {
          ["@attributes"]=>
          array(1) {
            ["name"]=>
            string(9) "Specialty"
          }
        }
        [4]=>
        object(SimpleXMLElement)#6 (1) {
          ["@attributes"]=>
          array(1) {
            ["name"]=>
            string(7) "User ID"
          }
        }
        [5]=>
        object(SimpleXMLElement)#7 (1) {
          ["@attributes"]=>
          array(1) {
            ["name"]=>
            string(13) "Display First"
          }
        }
        [6]=>
        object(SimpleXMLElement)#8 (1) {
          ["@attributes"]=>
          array(1) {
            ["name"]=>
            string(12) "Display Last"
          }
        }
      }
    }
  }
}

How could I retrieve the Company and Email values, or any specific field from there, which I don't know if is empty or has a value.

I don't see the field name for those with a value and I can't assume the fields order.

Edit: I don't think this is a duplicate as @Rizier123 said, as I'm trying to retrieve an item based on an element attribute, and I'm not even getting on the var_dump the attributes for the fields that have a value. Thus, the proposed and accepted solutions for that other question don't apply here. As he asked, I'm adding the full and real code that I'm using to test this:

$response = '<result>
    <contact id="1" date="1424746532" dlm="1425357692" score="0.00" purl="" bulk_mail="1">
        <Group_Tag name="Contact Information">
            <field name="Company">Test.com</field>
            <field name="Email">test@test.com</field>
            <field name="Group"/>
            <field name="Specialty"/>
            <field name="User ID"/>
            <field name="Display First"/>
            <field name="Display Last"/>
        </Group_Tag>
    </contact>
</result>';
$responseData = simplexml_load_string($response);
var_dump($responseData);
Nazareno Lorenzo
  • 1,069
  • 2
  • 14
  • 25
  • @Rizier123 I don't think this is a duplicate, as I'm trying to retrieve an item based on an element attribute, and I'm not even getting on the var_dump the attributes for the fields that have a value. Thus, the proposed and accepted solutions for that other question don't apply here. – Nazareno Lorenzo Mar 09 '15 at 21:10
  • Then please also include the code how you get the xml and how you print it! (Your **full** and **real** code) – Rizier123 Mar 09 '15 at 21:12
  • @Rizier123 Done. I don't think that it adds anything interesting, but I added it. Its my **full** and **real** code, as I'm working on a bare minimal test first. – Nazareno Lorenzo Mar 09 '15 at 21:16
  • 1
    Have you tried to loop thru "field" array and get the attribute with $field[n]->attributes()? Does it returns anything? – Luciano Mar 09 '15 at 21:56

1 Answers1

0

As @luciano suggested on a comment, I fixed this iterating through the field array using $field[n]->attributes()

SimpleXML doesn't shows the attributes and text at the same time for any element when you're using print_r(), var_dump() or any function that tries to cast the values to a string. The get_properties handler for SimpleXML lies in a few things, for example, showing @attributes as a property although it isn't accessible.

The only way to retrieve both the attributes and text from an element, is iterating through it and manually asking for each using $field->attributes() and $field casted as string.

The final code for my case was:

$responseData = simplexml_load_string($response);
$fields = $responseData->contact[0]->Group_Tag->field;
foreach ($fields as $field) {
    printf("%s : %s \n\r",
        $field->attributes()->name,
        $field);
}
Nazareno Lorenzo
  • 1,069
  • 2
  • 14
  • 25
  • 2
    Attributes are as well accessible via *`ArrayAccess`*, that is `$field['name']` will give you the *name* attribute value of the element-node represented by `$field`. It's perhaps a bit shorter than `$field->attributes()->name` which allows you to specify the namespace of the attributes you're looking for (not used in your example). --- And `[0]` in `$responseData->contact[0]->Group_Tag->...` is superfluous as when you traverse deeper, the first element is taken automatically. Just FYI. --- And most important: Don't use `var_dump` or `print_r` just use `echo $xml->asXML();` and look on the XML. – hakre Mar 09 '15 at 22:50