Skip to content

Commit

Permalink
Changed XSD parser to parse custom elements
Browse files Browse the repository at this point in the history
  • Loading branch information
Puraskar Sapkota committed Apr 5, 2016
1 parent 9949dd8 commit fa6226a
Showing 1 changed file with 102 additions and 0 deletions.
102 changes: 102 additions & 0 deletions Generator/Parser/XsdParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ protected function addChildrenElements($parentNode, &$parentElement)
$this->setComplexTypeChildrenRecursively($node, $element);

$parentElement->addChild($element);

} elseif ($this->isCustomTypeNode($node)) {
$element = new Parser\Element\ComplexTypeElement();
$element->setName($node->getAttribute('name'));
$this->setCustomTypeChildrenRecursively($node, $element);

$parentElement->addChild($element);

} else {
$element = new Parser\Element\Element();
$element->setName($node->getAttribute('name'));
Expand Down Expand Up @@ -155,4 +163,98 @@ protected function setComplexTypeChildrenRecursively($node, &$element)
}
}
}


/**
* Checks if the node is custom Type which is user Defined.
* It is a Complex type but name given by user.
*
* If given type of the element is not ComplexType but there is root level element with that name,
* it is supposed to be custom Node..
*
* Example of XML
* <?xml version="1.0" encoding="UTF-8"?>
* <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="oUm">

This comment has been minimized.

Copy link
@SvetlinStaevWorldstores

SvetlinStaevWorldstores Apr 5, 2016

Member

It is a good idea to have that example in the documentation rather than breaking the doc block with the xsd content.

<xs:annotation>
<xs:documentation>This is an example of complex Element</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="id">
<xs:annotation>
<xs:documentation>Unique id</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="100"/>
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="billToAddress" type="addressType" minOccurs="0">
<xs:annotation>
<xs:documentation>Bill to address</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="address" type="addressType"/>
<xs:complexType name="addressType">
<xs:all>
<xs:element name="title" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>Customer title</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:schema>
*
* @param DomNode $node
*
* @return boolean
*/
protected function isCustomTypeNode($node)

This comment has been minimized.

Copy link
@SvetlinStaevWorldstores

SvetlinStaevWorldstores Apr 5, 2016

Member

Type hinting the $node in the method signature will make the code more strict.

{
$nodes = $this->start->childNodes;

$nodeType = $node->nodeType;
$typeAttribute = $node->getAttribute('type');

if ($nodeType === XML_ELEMENT_NODE) {

This comment has been minimized.

Copy link
@SvetlinStaevWorldstores

SvetlinStaevWorldstores Apr 5, 2016

Member

The arrow-like conditionals could easily be eliminated with return-early-return-often approach for easier read and testability.

if (!empty($typeAttribute)) {

This comment has been minimized.

Copy link
@SvetlinStaevWorldstores

SvetlinStaevWorldstores Apr 5, 2016

Member

Checking the attribute type for being not being null will be faster since empty checks other structures.

foreach ($nodes as $node) {
//If any Node exists with the same name as Attribute Type defined for any element
if (method_exists($node, 'getAttribute')) {

This comment has been minimized.

Copy link
@SvetlinStaevWorldstores

SvetlinStaevWorldstores Apr 5, 2016

Member

Isn't it better to have a hasser in the node element to define whether it has attributes or not and thus the check will be $node->hasAttribute('name')

if ($typeAttribute === $node->getAttribute('name')) {

This comment has been minimized.

Copy link
@SvetlinStaevWorldstores

SvetlinStaevWorldstores Apr 5, 2016

Member

The two nested ifs could be bound together.

return true;
}
}
}
}
}

This comment has been minimized.

Copy link
@SvetlinStaevWorldstores

SvetlinStaevWorldstores Apr 5, 2016

Member

It will be a bit more readable to have a space before the return in the method.

return false;
}

/**
* Sets Children of Custom Type Recursively
* @param DomNode $node
* @param Element $element
*/
protected function setCustomTypeChildrenRecursively($node, &$element)

This comment has been minimized.

Copy link
@SvetlinStaevWorldstores

SvetlinStaevWorldstores Apr 5, 2016

Member

It is a good idea to type hint the arguments.

{
$nodes = $this->start->childNodes;
$typeAttribute = $node->getAttribute('type');

foreach ($nodes as $node) {
//If any Node exists with the same name as Attribute Type defined for any element
if (method_exists($node, 'getAttribute')) {
if ($typeAttribute === $node->getAttribute('name')) {
$this->addChildrenElements($node, $element);
}
}
}
}
}

0 comments on commit fa6226a

Please sign in to comment.