Parse XSD file in PHP and display the elements in the XSD
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.
Kevin
Updated on June 04, 2022Comments
-
Kevin about 2 years
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.
-
FantomX1 almost 6 yearsthanks works, I just don't like the global variables used there, and surprisingly that php doesn't support parsing xsd documents, as its also just a type of xml
-
kjhughes almost 6 years@FantomX1: PHP does support parsing XSD as XML as shown in this answer. "Global" variables in a demo / code snippet shouldn't bother you; it's easy to button-up working code -- this is just a demo to get people started or unstuck.