Giter Site home page Giter Site logo

xsd-reader's Introduction

Build status Code Coverage Badge

PHP XSD Reader

Read any XML Schema (XSD) programmatically with PHP.

Installation

The recommended way to install the xsd-reader via Composer:

composer require 'goetas-webservices/xsd-reader'

Getting started

use GoetasWebservices\XML\XSDReader\SchemaReader;

$reader = new SchemaReader();
$schema = $reader->readFile("http://www.example.com/example.xsd");

// $schema is instance of GoetasWebservices\XML\XSDReader\Schema\Schema;

// Now you can navigate the entire schema structure

foreach ($schema->getSchemas() as $innerSchema) {

}
foreach ($schema->getTypes() as $type) {

}
foreach ($schema->getElements() as $element) {

}
foreach ($schema->getGroups() as $group) {

}
foreach ($schema->getAttributes() as $attr) {

}
foreach ($schema->getAttributeGroups() as $attrGroup) {

}

Note

The code in this project is provided under the MIT license. For professional support contact [email protected] or visit https://www.goetas.com

xsd-reader's People

Contributors

allcode avatar cebe avatar davidsonalencar avatar github-actions[bot] avatar goetas avatar guite avatar holtkamp avatar jbuncle avatar mgrundkoetter avatar rsully avatar rvdbogerd avatar signpostmarv avatar toilal avatar toooni avatar veewee avatar zambodaniel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

xsd-reader's Issues

Progress Report Callback

This is more of an FYI than an issue or enhancement request, but it's here if you're interested. When testing to figure out the problem with #55 I had needed to add reporting diagnostics to the getDOM method... and I wanted to keep them, so I was about to add it to my local copy, when I ran into an unrelated issue involving getting the namespace data (including the prefix) from the data, and realized I needed to do it on all the imported files.

I realized I could make a more generic reporting mechanism that would let me handle this - there are now several places in SchemaReader.php in my fork of the code where it calls a reporting function, which does nothing unless the caller has set a reporting callback, in which case the reporting function forwards the report to the callback.

This was ideal for my use case - through it, I can now see a progress report, as well as extract all the namespace information from each XSD document as it's imported. I'm not sure if this is worth a PR as my use case was specialized, but it's in steve962@38dea60 if anyone is interested.

Replacement for goetas/xsd-reader?

If this is a replacement for goetas/xsd-reader, please add the following to the composer.json definition so packages that use xsd-reader as a dependency can use the new package.

"replace": { "goetas/xsd-reader": "2.*@dev" }

Seemingly infinite loop

Hi, when I try to use the xsd reader as described in the readme and I try something simple, such as

$reader = new SchemaReader();
$schema = $reader->readFile($xsdName);
foreach ($schema->getTypes() as $type){
    var_dump($type);
    die();
}

the output goes on and on and on. I would think there is an error somewhere in the reader, but can't figure out what it is, having seen this code for the first time an hour ago..

Schemas are valid.
The XSD I'm trying to read is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://localhost:8070/schemas/v1/endpoints/basic/sports.xsd" xmlns:v1="http://localhost:8070/schemas/v1/endpoints/basic/sports.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="../../includes/common/sport.xsd" />
  <xs:element name="sports" type="v1:sportsType" />
  <xs:complexType name="sportsType">
    <xs:sequence>
      <xs:element type="v1:sportType" name="sport" maxOccurs="unbounded" minOccurs="0" />
    </xs:sequence>
    <xs:attribute type="xs:dateTime" name="generated_at"/>
  </xs:complexType>
</xs:schema>

and imports:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:include schemaLocation="urn.xsd" />
    <xs:complexType name="sportType">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute type="sportUrnType" name="id" use="required"/>
                <xs:attribute type="xs:string" name="name" use="required"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:simpleType name="sportUrnType">
        <xs:restriction base="xs:string">
            <xs:pattern value="sr:sport:[0-9]+"/>
        </xs:restriction>
</xs:schema>

Some servers answer with HTTP Status 500 without user agent set

Tried to convert the REQIF definition with xsd2php and got an error which is caused by xsd-reader:

> C:\webserver\php-7.0.8\composer.bat build

C:\Users\fastnacht\PhpstormProjects\staffgraph-req>"C:\webserver\php-7.0.8\php.exe" "C:\webserver\php-7.0.8\composer.phar" build 
> xsd2php convert:php reqif.xsd --ns-map=http://www.omg.org/spec/ReqIF/20110401/reqif.xsd;jfastnacht/REQIF --ns-dest=jfastnacht/REQIF/;src/jfastnacht/REQIF
Namespaces:
    XML namepsace: http://www.omg.org/spec/ReqIF/20110401/reqif.xsd => PHP namepsace: jfastnacht/REQIF
Target directories:
    PHP namepsace: jfastnacht/REQIF/ => Destination directory: src/jfastnacht/REQIF
Reading reqif.xsd

Script xsd2php convert:php reqif.xsd --ns-map=http://www.omg.org/spec/ReqIF/20110401/reqif.xsd;jfastnacht/REQIF --ns-dest=jfastnacht/REQIF/;src/jfastnacht/REQIF handling the build event returned with an error

Warning: DOMDocument::load(http://www.w3.org/TR/xhtml-modularization/SCHEMA/xhtml-datatypes-1.xsd): failed to open stream: HTTP request failed! HTTP/1.0 500 Server Error
 in C:\Users\fastnacht\PhpstormProjects\staffgraph-req\vendor\goetas-webservices\xsd-reader\src\SchemaReader.php on line 758

Warning: DOMDocument::load(): I/O warning : failed to load external entity "http://www.w3.org/TR/xhtml-modularization/SCHEMA/xhtml-datatypes-1.xsd" in C:\Users\fastnacht\PhpstormProjects\staffgraph-req\vendor\goetas-webservices\xsd-reader\src\SchemaReader.php on line 758


  [GoetasWebservices\XML\XSDReader\Exception\IOException]                      
  Can't load the file http://www.w3.org/TR/xhtml-modularization/SCHEMA/xhtml-  
  datatypes-1.xsd                                                              


convert:php [--ns-map NS-MAP] [--ns-dest NS-DEST] [--alias-map ALIAS-MAP] [--naming-strategy NAMING-STRATEGY] [--] <src> (<src>)...

PHP Warning:  DOMDocument::load(http://www.w3.org/TR/xhtml-modularization/SCHEMA/xhtml-datatypes-1.xsd): failed to open stream: HTTP request failed! HTTP/1.0 500 Server Error
 in C:\Users\fastnacht\PhpstormProjects\staffgraph-req\vendor\goetas-webservices\xsd-reader\src\SchemaReader.php on line 758
PHP Warning:  DOMDocument::load(): I/O warning : failed to load external entity "http://www.w3.org/TR/xhtml-modularization/SCHEMA/xhtml-datatypes-1.xsd" in C:\Users\fastnacht\PhpstormProjects\staffgraph-req\vendor\goetas-webservices\xsd-reader\src\SchemaReader.php on line 758

  [RuntimeException]                                                           
  Error Output:                                                                


    [GoetasWebservices\XML\XSDReader\Exception\IOException]                    

    Can't load the file http://www.w3.org/TR/xhtml-modularization/SCHEMA/xhtm  
  l-                                                                           
    datatypes-1.xsd                                                            



  convert:php [--ns-map NS-MAP] [--ns-dest NS-DEST] [--alias-map ALIAS-MAP] [  
  --naming-strategy NAMING-STRATEGY] [--] <src> (<src>)...                     
  PHP Warning:  DOMDocument::load(http://www.w3.org/TR/xhtml-modularization/S  
  CHEMA/xhtml-datatypes-1.xsd): failed to open stream: HTTP request failed! H  
  TTP/1.0 500 Server Error                                                     
   in C:\Users\fastnacht\PhpstormProjects\staffgraph-req\vendor\goetas-webser  
  vices\xsd-reader\src\SchemaReader.php on line 758                            
  PHP Warning:  DOMDocument::load(): I/O warning : failed to load external en  
  tity "http://www.w3.org/TR/xhtml-modularization/SCHEMA/xhtml-datatypes-1.xs  
  d" in C:\Users\fastnacht\PhpstormProjects\staffgraph-req\vendor\goetas-webs  
  ervices\xsd-reader\src\SchemaReader.php on line 758                          


build [--dev] [--no-dev] [--] [<args>]...


Process finished with exit code 1 at 13:53:33.
Execution time: 16.898 ms.

Composer build script:

"scripts": {
  "build": "xsd2php convert:php reqif.xsd --ns-map=http://www.omg.org/spec/ReqIF/20110401/reqif.xsd;jfastnacht/REQIF --ns-dest=jfastnacht/REQIF/;src/jfastnacht/REQIF"
}

Fixed it with a comment on https://secure.php.net/manual/de/domdocument.load.php#91384 by adding:

$opts = array(
    'http' => array(
        'user_agent' => 'PHP libxml agent',
    )
);
$context = stream_context_create($opts);
libxml_set_streams_context($context);

between

$xml = new DOMDocument('1.0', 'UTF-8');
if (!$xml->load($file)) {

Might help someone else with the same problem. This is just a quick and dirty solution if you need it right now.

Required dev-dependencies

Hello,

In composer.json, you can find these requires:

xsd-reader/composer.json

Lines 21 to 23 in a434167

"require" : {
"php": "^7.1|^8.0",
"vimeo/psalm": "^3.14"

Shouldn't psalm be a dev-dependency?

Currently, this is pulling in an older version of psalm, resulting in unwanted conflicts.

getDoc() empty for Elements

Assuming an xsd node like

<xsd:element name="bewertung">
	<xsd:annotation>
		<xsd:documentation>Container für detailierte Bewertungs Parmater</xsd:documentation>
	</xsd:annotation>
	<xsd:complexType>
		...
	</xsd:complexType>
</xsd:element>

the xsd parser returns always an empty doc for $element->getDoc(). I was able to fix this by just adding
$attribute->setDoc($this->getDocumentation($node)); in Schemareader->loadAttributeOrElementDef() in the else branch after $attribute = new ElementDef($schema, $name);

Is this behavior intended/is there a reason for not parsing the documentation for elements? If not, this would be a nice feature! I generate PHP code based on a given xsd and this would allow for some more useful class docblock :-) (see https://github.com/ujamii/openimmo/blob/master/src/Generator/ApiGenerator.php)

I can open a PR if you consider this useful.

Ability to identify element children either of complex or sequence or etc

Hi,
Is there a way to identify if the children of the element are from sequence or choice or any other tag.
Right now, I am able to get the children but not the type. Is this in the scope of the project?
Here is an example.
` <xsd:complexType name="Parent">

    <xsd:sequence>

        <xsd:element name="child1" type="wsg:child1" minOccurs="0" />

        <xsd:element name="child2" type="wsg:child2" />

        <xsd:element name="child3" type="wsg:child3" minOccurs="0" />

    </xsd:sequence>

</xsd:complexType>`

Basically, I would prefer If i could get that it's type sequence or choice or something similar.

Choise tag in ComplexType

Hello. I have a few problem with parse XSD. The first is SchemaReader Class doesn't have a opportunity to parse totalDigits, fractionDigits restriction. Becouse of that I create own class with almost content. And the second is ComplexType with choise tag parses like sequence, but didn't. Thanks.

re-enabling code coverage for scrutinzer

back in the static-analysis branch, I'd enabled tests & code coverage to run internally, but it was turned off at your request- we've seen recently that scrutinizer inspections have failed because it was waiting for code coverage from travis.

I've currently got a branch ready for re-enabling psalm tests on xsd-reader, but it's been stuck for 2 hours on the code coverage element.

Any chance we can re-enable tests & code coverage on scrutinizer?

Having issues finding the default value

So I am parsing out a xsd file and everything is working awesome.

But I don't see anyway to grab the default value.

<xsd:element default="2000" maxOccurs="1" minOccurs="1" name="port" nillable="false" type="integer"/>

Is there anyway to find that default value of 2000?

forking out php-cs-fixer config

I've started running static analysis on xsd2php, and as mentioned somewhere back in one of the static analysis issues/prs on this repo you may recall I mooted the idea of the future possiblity of having a shared package for php-cs-fixer configs for the repos. as part of that work I've done a git rebase /filter on xsd-reader to create the composer-ready package

the repo includes a text file that lists the shell commands used to create the repo from this one.

what I'm hoping is that at your convenience you peruse the repo, then we arrange to transfer the repo over to you & we switch xsd-reader to use that package (as well as removing the repositories entry in composer.json on the xsd2php static analysis branch.

looking forward to hearing your thoughts :)

Global/Local element partial interpretation of formDefaultElement="unqualified"

Requests generated by soap-client may have missing namespace prefixes on some elements because of a misinterpretation of formDefaultElement attribute.

Please read this source about how elementFormDefault and attributeFormDefault should be interpreted: https://www.intertech.com/Blog/xml-schema-elementformdefault-and-attributeformdefault

elementFormDefault=”unqualified”

Setting this attribute to “unqualified” means all global elements from this schema must be qualified, and all local elements must be unqualified, when used in an XML document.

This article makes a difference between Global and Local elements, but it seems this library doesn't implement this difference.

Here's the WSDL that cause the issue: https://afis.id3.eu/BiometricIdServices/Id3BiometricIdServicePort?wsdl

It's related to an XSD using elementFormDefault="unqualified" here:
http://afis.id3.eu/BiometricIdServices/Id3BiometricIdServicePort?xsd=Id3BiometricIdService_schema5.xsd

With this WSDL, when invoking IdentifySubject action, the generated request is missing the namespace on IdentifySubjectRequest node, causing a SOAP Fault from the server.

<?xml version="1.0" encoding="UTF-8"?>
<SOAP:Envelope xmlns:SOAP="http://www.w3.org/2003/05/soap-envelope">
  <SOAP:Body>
    <ns-4c7934d9:IdentifySubject xmlns:ns-4c7934d9="http://biometricid.id3.eu/">
      <IdentifySubjectRequest>
        <data>
          <FingerDataRecord>
            ...
          </FingerDataRecord>
        </data>
      </IdentifySubjectRequest>
    </ns-4c7934d9:IdentifySubject>
  </SOAP:Body>
</SOAP:Envelope>

According to the Blog article, as elementFormDefault is set to unqualified in related XSD and IdentifySubjectRequest is a Global element inside the XSD, it should be prefixed.

When importing this WSDL in SoapUI, generated requests are valid with the namespace prefix on IdentifySubjectRequest and SoapUI can consume the web service properly.

I think this issue belongs to xsd-reader more than xsd2php, because xsd-reader could provide the global/local information on parsed elements, so that xsd2php can use this information to generate JMS mapping properly.

loadElement xs:choice $element->setMin(0)

Hi,
i'm currently working on a project with OpenTravel-Data called Alpinebits.

(Sorry, i'm not 100% sure, if i am in the correct project because it could also fit better in the xsd2php project).

I am using xsd2php to generate the classes and the JMS-Metadata.

The problem is that a property has the skip_when_empty: true-Flag in the metadata-file und therefore the property is not serialized.

i checked it and found out that the minOccurs was set to 0 in this if-block:

if ($xp->query('ancestor::xs:choice', $node)->length) {
$element->setMin(0);
}

i think the xpath-query should only check the first anchestor (parent) or am i wrong?

method-schema

<xs:element name="OTA_ResRetrieveRS">
    <xs:complexType>

      <xs:choice>
        <!-- choice: Errors {1} -->
        <xs:element name="Errors">
          <xs:complexType>
            ...
          </xs:complexType>
        </xs:element>

        <!-- choice: Success {1} + Warnings {0,1} + ReservationsList {1} -->
        <xs:sequence>
          <xs:element name="Success"/>
          <xs:element name="Warnings" minOccurs="0">
            <xs:complexType>
             ...
            </xs:complexType>
          </xs:element>
          <xs:element name="ReservationsList">
            <xs:complexType>
              <xs:sequence>
                <!-- HotelReservation {0,} -->
                <xs:element name="HotelReservation" maxOccurs="unbounded" minOccurs="0">
                   ...
                </xs:element>
              </xs:sequence>
            </xs:complexType>
          </xs:element>

        </xs:sequence>

      </xs:choice>

    </xs:complexType>
  </xs:element>

method-response

<?xml version="1.0" encoding="UTF-8"?>
<OTA_ResRetrieveRS xmlns="http://www.opentravel.org/OTA/2003/05" Version="1.00">
  <Success><![CDATA[1]]></Success>
</OTA_ResRetrieveRS>

Spelling errors

HI
you have spelling errors in the SchemaReader.php on line 535-538.
the i's are missing. has to be minInclusive, and so on ...

Create a new release

Could you create a new release. The getDefault stuff is not available. I would like to not use dev-master in my composer.json

Keeping the order of a mixed sequence

Hi,

I'm currently working on a project where a complex type may contain a sequence of mixed types, i.e.

<choice maxOccurs="unbounded">
    <element name="label" type="ns:labelType"/>
    <element name="text" type="ns:textType"/>
    <element name="select" type="ns:selectType"/>
    <element name="checkbox" type="ns:checkboxType"/>
 </choice>

The generated classes nicely group them into different attributes BUT I really need to keep track of the actual order of those in the XML I'm parsing. Is there any way to do this using xsd2php?

Request to support multi language xs:documentation annotations

Currently, if there are multiple language documentation tags in an annotation, they are concatenated together in one single line.
See attached screenshots. I'll submit a PR to resolve this, by adding a line break if there are multiple docs for a node.

Screenshot from 2020-10-16 11-43-55
Screenshot from 2020-10-16 11-44-26

request for code style configs

  • a .editorconfig file would be handy for ensuring contributors have a consistent line ending/ indentation style (or at least those that use an editor supporting it) - handled in #20
  • having a config file for friendsofphp/php-cs-fixer would allow you to have a reasonably well defined code style which if defined as it's own composer package could be shared amongst all of your packages (here's one I made earlier)
    • adding @Symfony with yoda conditions disabled.

If we're going with a php-cs-fixer config, I'd suggest going beyond a base symfony/psr-2 style & browsing the available rules, since there's some rules that aren't part of the "standard" sets, or there might be some rules you don't like (i.e. if you think yoda conditions are weird) that could be turned off.

UrlUtils::replaceSuperfluousSlashes incorrectly handles multiple sets

I was trying to parse a complex XSD hierarchy using the NIEM 4.2 standard which uses a number of subdirectories and multiple relative path levels, and it was failing to find many of the files. I tracked the problem down to the src/Utils/UrlUtils.php module, where the static method replaceSuperfluousSlashes() was the culprit. Given a path like:

/home/username/docs/xsd/level1a/level2a/level3a/../../../level1b/somefile.xsd

...you would expect it to return:

/home/username/docs/xsd/level1b/somefile.xsd

...but instead it returns:

/home/username/docs/xsd/level1a/level2a/level1b/somefile.xsd

I resolved the problem in my situation by adding the following code to the beginning of the function:

        $rp = realpath($abs);
        if ($rp) {
            return $rp;
        }

...but I'm not sure if that's the right fix for every case, since I'm not sure why realpath() wasn't used in the first place.

ComplexType mixed="true"

Hi there,

is there a way to determine if a complex type has mixed set to true?

<xsd:complexType mixed="true">
...
</xsd:complexType>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.