Reputation: 3239
I have an XSD schema file that I want to parse and echo the elements that it contains, also if possible to display the children each element has as well. I have seen some examples, the best of which have the example of: Convert XSD file into array in PHP
I tried it and it gives me an empty array even after changing the xs: portion in xpaths and file location. Is there a proper way to parse an XSD file and display its elements in PHP?
To clear up any confusion here is what I am trying to say:
Lets say this is the XSD I am trying to load and display its elements (this comes from the link above):
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
As we can see there is an element with the name "shiporder" and it has children which are, If I am not mistaken, "orderperson" that has type string, It also has "shipto" that has children elements that are: "name", "address", "city", "country" that are of type string.
What I want to do is simply print out "shiporder" has children "orderperson" and "shipto" "shipto" has children "name", "address", "city", and "country".
How can I acheve this? Should I be using the method described below?:
<?php
$attributes = array();
$xsdstring = "test.xsd";
$XSDDOC = new DOMDocument();
$XSDDOC->preserveWhiteSpace = false;
if ($XSDDOC->load($xsdstring))
{
$xsdpath = new DOMXPath($XSDDOC);
$attributeNodes =
$xsdpath->
query('//xs:element[@name="shiporder"]')
->item(0);
foreach ($attributeNodes->childNodes as $attr)
{
$attributes[ $attr->getAttribute('value') ] = $attr->getAttribute('name');
}
unset($xsdpath);
}
print_r($attributes);
?>
Hopefully this makes my question a bit clearer, as I am new to php and xml parsing.
Upvotes: 4
Views: 20067
Reputation: 111551
This PHP:
<?php
$xsdstring = <<<XML
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
XML;
$doc = new DOMDocument();
$doc->loadXML(mb_convert_encoding($xsdstring, 'utf-8', mb_detect_encoding($xsdstring)));
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('xs', 'http://www.w3.org/2001/XMLSchema');
function echoElements($indent, $elementDef) {
global $doc, $xpath;
echo "<div>" . $indent . $elementDef->getAttribute('name') . "</div>\n";
$elementDefs = $xpath->evaluate("xs:complexType/xs:sequence/xs:element", $elementDef);
foreach($elementDefs as $elementDef) {
echoElements($indent . " ", $elementDef);
}
}
$elementDefs = $xpath->evaluate("/xs:schema/xs:element");
foreach($elementDefs as $elementDef) {
echoElements("", $elementDef);
}
?>
Yields the following output:
shiporder
orderperson
shipto
name
address
city
country
item
title
note
quantity
price
as requested.
Note that this assumes a simple Russian Doll XSD design that uses the basic embedded xs:complexType/xs:sequence/
structure as is found in the provided shiporder
definition and its descendant elements.
Upvotes: 7