Reputation: 8702
I got a XML file which contains a lot of lines like that:
<class name="CustomerProfileLite" inList="true" >
<enum name="Order" takeOtherValuesFromProperties="true">
<value>None</value>
</enum>
<property name="Guid" type="guid" />
<property name="CreationDate" type="datetime" isInEnum="true" />
<property name="LastUpdateDate" type="datetime" isIndexed="true" isInEnum="true" />
<property name="Revision" type="int" isIndexed="true" isInEnum="true" />
<property name="Thumbnail" type="string" convertToRelativePathInDB="true" />
<property name="UmsJob" type="string" isIndexed="true"/>
<property name="FirstName" type="string" isIndexed="true" isInEnum="true" />
<property name="LastName" type="string" isIndexed="true" isInEnum="true" />
<property name="Address" type="string" isInEnum="true" />
<property name="City" type="string" isInEnum="true" />
<property name="PhoneNumber" type="string" isIndexed="true" isInEnum="true" />
<property name="CellPhoneNumber" type="string" isIndexed="true" isInEnum="true" />
<property name="Birthdate" type="OptionalDateTime" isInEnum="true" />
<property name="HasFrames" type="bool" />
<property name="LatestEquipementHasFarVisionBoxings" type="bool" />
<property name="LatestEquipementHasFarVisionImages" type="bool" />
<property name="LatestEquipementHasSplines" type="bool" />
<property name="LatestEquipementHasIpadMeasure" type="bool" />
<sattribute name="IsModified" type="bool" />
<sattribute name="LastModificationDate" type="datetime" />
</class>
I need to get the class name and all it's properties. I also need to store all the enum values in a different array.
I've made the following code but I can't make it work properly. I can't get the property
children and the enum
list.
$this->struct_xml = simplexml_load_file("assets/archi.xml");
$archi = array();
$types = $this->struct_xml->xpath("type");
foreach ($types as $type) {
$name = (string) $type['name'];
$archi[$name] = array();
if ((bool) $type['isComplexType']) {
$class = first($this->struct_xml->xpath("class[@name='$name']"));
if (!$class) throw new Exception("Unknown type found $name !");
foreach ($class->children('property') as $property) {
$archi[$name]['children'][] = array(
'name' => (string) $property['name'],
'type' => (string) $property['type'],
);
}
}
}
$enums = $this->struct_xml->xpath("enum");
foreach ($enums as $enum) {
$name = (string) $type['name'];
$archi[$name] = array();
foreach ($enum->children() as $value) {
$archi[$name]['values'][] = $value;
}
}
The line $class->children('property')
returns an empty SimpleXMLElement
. Also the line $this->struct_xml->xpath("enum")
returns a null value whereas it should give me a list of enum.
Could you help me to fix it ?
Upvotes: 0
Views: 531
Reputation: 356
Please try this code to print your data, and add the conditions in that loop,
$this_struct_xml = simplexml_load_file("archi.xml"); //$this->struct_xml = $struct_xml;
foreach($this_struct_xml->property as $property) {
echo "name:".$property->attributes()->name." / ";
echo "type:".$property->attributes()->type." / ";
echo "isInEnum:".$property->attributes()->isInEnum." / ";
echo "isIndexed:".$property->attributes()->isIndexed."<br/>";
}
echo "-------------------------------<br/>";
foreach($this_struct_xml->enum as $enum) {
echo "name:".$enum->attributes()->name." / ";
echo "type:".$enum->attributes()->takeOtherValuesFromProperties." / ";
echo "Value:".$enum->value."<br/>";
}
Upvotes: 1
Reputation: 10070
The line
$class->children('property')
returns an emptySimpleXMLElement
While SimpleXMLElement::children()
refers to the children of the current element, its first parameter is to indicate namespace, not tag name.
So $class->children('property')
means to check for child element in $class
that is in namespace property
.
You can just use $class->property
to retrieve a "list" of all <property>
tag inside that class;
the line
$this->struct_xml->xpath("enum")
returns a null value whereas it should give me a list of enum
XPath is not like document.getElementByTagName
in HTML DOM. You have to at least specify that the tag is a child of something. The lazy form would be xpath("//enum")
.
$dom=simplexml_load_file("xml");
foreach($dom->xpath("//class") as $class)
{
echo (string)$class["name"];
echo "\n";
foreach($class->property as $property)
{
echo (string)$property["name"];
echo "\t";
echo (string)$property["type"];
echo "\n";
}
}
foreach($dom->xpath("//enum") as $enum)
{
echo (string)$enum["name"];
echo "\t";
echo (string)$enum->value;
}
Outputs:
CustomerProfileLite
Guid guid
CreationDate datetime
LastUpdateDate datetime
Revision int
...
Order None
Upvotes: 2
Reputation: 1259
The parameter of SimpleXML::children is for getting childs with a specific namespace prefix. You have to point directly to the node. For example:
$class->property->children()
For further informations about namespaces and prefixes look at http://www.w3schools.com/xml/xml_namespaces.asp
Upvotes: 1