willemdj / erlsom

XML parser for Erlang
GNU Lesser General Public License v3.0
264 stars 103 forks source link

Restrictions in model when using compile_xsd_file #71

Open kuffel opened 5 years ago

kuffel commented 5 years ago

Is it possible to get the restrictions from the XSD file when using compile_xsd_file function?

Example XSD

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:complexType name="restrictions_test">
    <xsd:sequence>
      <xsd:element name="range" >
        <xsd:simpleType>
          <xsd:restriction base="xsd:integer" >
            <xsd:minInclusive value="0"/>
            <xsd:maxInclusive value="42"/>
          </xsd:restriction>
        </xsd:simpleType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

The model returned by compile_xsd_file does not contain the restriction:

{:model,
 [
   {:type, :_document, :sequence, [{:el, [], 1, 1, :undefined, 2}], [],
    :undefined, :undefined, 1, 1, 1, false, :undefined},
   {:type, :restrictions_test, :sequence,
    [
      {:el, [{:alt, :range, {:"#PCDATA", :char}, [], 1, 1, true, :undefined}],
       1, 1, :undefined, 2}
    ], [], :undefined, :undefined, 2, 1, 1, :undefined, :undefined}
 ], [{:ns, 'http://www.w3.org/2001/XMLSchema', 'xsd', :qualified}], :undefined,
 [], false, :skip}

Is there any option to allow getting the content of the restriction?

willemdj commented 5 years ago

If you mean: an option to ensure that the parser enforces the restriction, the answer is no. The parser only checks the structure of the XML documents, restrictions like minInclusive and maxInclusive are not checked.

If you are looking for a way to somehow inspect the XSD (your question sort of suggests that?) then you could try erlsom_parseXsd:parseXsd/2.

kuffel commented 5 years ago

Thanks for the quick response! Yes i am looking for a way to inspect the XSD.

For this XSD:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:simpleType name="SKU">
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="\d{3}-[A-Z]{2}"/>
    </xsd:restriction>
  </xsd:simpleType>
</xsd:schema>

i get this result:

{:schemaType, [], :undefined, :undefined, :undefined, :undefined, :undefined,
 :undefined, :undefined, :undefined,
 [{:globalSimpleTypeType, [], 'SKU', :undefined, :undefined, :undefined}]}

I would have expected the pattern somewhere in the result, but its missing. What can i do to get this pattern?

willemdj commented 5 years ago

Hm, I tried this:

Xsd = <<"<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
  <xsd:simpleType name=\"SKU\">
    <xsd:restriction base=\"xsd:string\">
      <xsd:pattern value=\"\\\d{3}-[A-Z]{2}\"/>
    </xsd:restriction>
  </xsd:simpleType>
</xsd:schema>">>,
erlsom_parseXsd:parseXsd(Xsd, []).

But that gives:

{schemaType,[],undefined,undefined,undefined,undefined,
            undefined,undefined,undefined,undefined,
            [{globalSimpleTypeType,[],"SKU",undefined,undefined,
                                   undefined}]}

So the information you are looking for is not there either.

It means that there is no simple way to do this using erlsom, I am afraid. The most logical way to do it would be to compile the schema for XML Schema, and then parse the XSD using that model. But unfortunately that won't work; for some reason erlsom does not accept the XSD for XML Schema.

What you could do is have a look at the module parseXsd.erl, and extend the 'xsdModel' that is returned by the function xsdModel. Alternatively you can parse the XSD using the SAX mode or the "simple DOM mode". But either way you will have to puzzle a bit, sorry.