MichielCM / xsd2html2xml

Generates plain HTML5 forms from XML schemas (XSDs). Transforms filled-in forms into XML.
MIT License
95 stars 42 forks source link

namespace in xml file must be identical to xsd file #22

Closed kgi-github closed 5 years ago

kgi-github commented 5 years ago

btw I meant to say Hi again in my previous issue. I am been otherwise occupied for a while, but revisiting my xsd project.

I have an issue where namespaces in the xml file must be explicit and given the same name as in the xsd file.

For example, my file test.xsd defines a namespace "example" as "http://my.example.com":

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:example="http://my.example.com"
    targetNamespace="http://my.example.com"
    elementFormDefault="qualified">

    <xs:complexType name="MyType">
    <xs:sequence>
        <xs:element name="integerField" type="xs:integer"/>
    </xs:sequence>
    </xs:complexType>

    <xs:element name="myThing" type="example:MyType"/>

</xs:schema>

Then my xml file myTest.xml declares "xlmns="http://my.example.com" but this isn't sufficient: the value 1974 is not displayed in the generated form:

<myThing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="test.xsd"
    xmlns="http://my.example.com">
        <integerField>1974</integerField>
</myThing>

If I define a namespace called "ex" instead of "example", it still isn't sufficient:

<ex:myThing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="test.xsd"
    xmlns:ex="http://my.example.com">
        <ex:integerField>1974</ex:integerField>
</ex:myThing>

However if I define the namespace "example" as in the xsd file, the value 1974 is shown in the generated form:

<example:myThing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="test.xsd"
    xmlns:example="http://my.example.com">
        <example:integerField>1974</example:integerField>
</example:myThing>
MichielCM commented 5 years ago

Yes, that's right. All namespaces and their prefixes are loaded into a root-namespaces variable and used throughout the stylesheets. So yes, (1) all namespaces should be declared in the root XSD, and (2) all prefixes (or lack thereof) should be the equal in all XSDs.

I realize it's an annoying limitation. I'll put it on the TODO-list for improvements... ;)

kgi-github commented 5 years ago

I understand. And it seems namespaces must be equal in the xml file too.

kgi-github commented 5 years ago

Hi Michiel, This is not an "issue" so didn't want to open a new one. Just a question: is it possible to define an element in an xsd file as "readonly" in the sense that the html form will not allow editing (nor require a particular value) but the value can be set in an xml file and displayed (readonly) in a generated filled form (and included when the form is submitted)? My use case is an ID field, which is managed by the server, and cannot be changed via an html form. I guess it could also be hidden in the html form, but still included when the form is submitted so the server knows the relevant ID. Kevin.

MichielCM commented 5 years ago

Hi Kevin,

Yes, using 'fixed' attributes will make an element visible but not editable in a form.

Best, Michiel

kgi-github commented 5 years ago

However if the element is fixed to say 0, if I'm not mistaken this will override the value in a generated filled form instead of using the value in the xml file, which is what I need. So I need the ID to be unchangeable by the user through the form, but still be used as normal in every other way (i.e. have a value in xml file which is included in form submissions).

MichielCM commented 5 years ago

Ah, in that case, no. The value in the XML file wouldn't be valid according to the XSD with 'fixed=0' anyway.

I think your best bet is to disable the (and optionally hide) the input element through CSS.

kgi-github commented 5 years ago

ok thanks, will think about a workaround along those lines.

kgi-github commented 5 years ago

Hi Michiel, I am enjoying using xsd2html2xml so thanks again. Another question, which may not be an "issue" so not opening a new one: is there a way to specify a string type that allows the empty string? I have tried a restriction on xs:string with a regexp that permits empties but the generated form still expects a non-empty value and complains that the field is not filled in. Let me know if you would prefer such questions in a new issue or simply by email. cheers, Kevin.

MichielCM commented 5 years ago

Hi Kevin,

I don't think an empty string is a valid xs:string type. Use minOccurs="0" for elements or use="optional" for attributes instead.

The issues board is fine for these kinds of questions.

Best regards, Michiel

kgi-github commented 5 years ago

Hi, This page indicates that an empty string is a valid xs:string value https://www.oxygenxml.com/forum/topic1864.html And this validator allows an empty string for an xs:string type https://www.liquid-technologies.com/online-xsd-validator So I’m inclined to think it’s legal. Perhaps try your favourite validator? Kevin.

MichielCM commented 5 years ago

Hi Kevin,

I'm not yet convinved... ;) The XSD Datatypes documentation is not all that specific about it. But I'm inclined to think you're right, judging from the behavior of the validators.

However, I think that in 99% of the use cases people will expect those fields to be non-empty. So implementing it as default on text fields would not be a good solution. But making fields optional if the type definition contains an xs:pattern which allows for empty strings, or has an xs:minLength of 0, or is nillable, could work well.

In the meantime, either try changing the schema with minOccurs="0", or edit the XSLT directly to remove the required attribute for text fields.

Best regards, Michiel

kgi-github commented 5 years ago

Yep, I think your proposed solutions (pattern with empty, or minLength=0) would solve the problem well. Please let me know if/when you implement one. In the meantime I'll use one of the workarounds. Thanks, Kevin.

MichielCM commented 5 years ago

Hi Kevin,

The latest commit has support for minLength="0" built-in for strings, normalized strings, and tokens. Both textfields and textareas with that property are generated as optional elements.

Best regards, Michiel

kgi-github commented 5 years ago

Thanks! Will try it in the next few days.

kgi-github commented 5 years ago

Hey there, I'm not sure if I'm doing something wrong but can't get minLength="0" to work for strings. I have this test file:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:simpleType name="stringType">
        <xs:restriction base="xs:string">
            <xs:minLength value="0"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="root">
        <xs:sequence>
            <xs:element name="el1" type="xs:string" minLength="0"/>
            <xs:element name="el2" type="stringType"/>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="rootElement" type="root"/>
</xs:schema>

and the generated form insists I fill in both el1 and el2. I'm not even sure if using minLength in the way I use in el1 definition is legal but thought I'd try. Certainly in the restriction it's legal. Let me know your thoughts. Kevin.

MichielCM commented 5 years ago

Your code works for me. el2 is optional, el1 has incorrect syntax.

Are you sure you are using the latest commit, not the latest release?

kgi-github commented 5 years ago

doh! got the latest commit and works like a charm. Thanks!

On another matter, is there a way to specify the directory to look in for xsd files that are referenced by an xml file when doing xml to html (i.e. generating a filled form)?

MichielCM commented 5 years ago

Nice. You can point to an XSD schema from an XML file through an xsi:schemaLocation attribute.

kgi-github commented 5 years ago

yep, thanks. It looks for the xsd file in the directory in which the xml file resides. Which is fine for me. K.

kgi-github commented 5 years ago

so i'm using the empty string fix, and have uncovered another issue. I completely understand if it takes some time to fix.

In the following example the element "el" is not optional (the form insists on a non-empty string). Its type is "stringExtension", which is an extension of an optional string type (i.e. of a restriction of string with minLength="0")

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:simpleType name="stringType">
        <xs:restriction base="xs:string">
            <xs:minLength value="0"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="stringExtension">
        <xs:simpleContent>
            <xs:extension base="stringType">
                <xs:attribute name="myAtt" type="xs:string" fixed="val"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="root">
        <xs:sequence>
            <xs:element name="el" type="stringExtension"/>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="rootElement" type="root"/>
</xs:schema>
MichielCM commented 5 years ago

Please check the latest commit, it should fix it.

kgi-github commented 5 years ago

It sure does, thanks Michiel.

A question: is there a way to have an attribute in the xml and xsd that is hidden in the html form?

MichielCM commented 5 years ago

Yes, you can use an annotation and hide the element with css.

This adds a class to your HTML element:

<xs:element type="xs:string" name="string" default="singleline string">
    <xs:annotation>
        <xs:appinfo source="https://github.com/MichielCM/xsd2html2xml">
            <class>hide</class>
        </xs:appinfo>
    </xs:annotation>
</xs:element>

And then hide it with CSS: .hide { display: none; }

Use the config-style parameter to point to your custom CSS file.

kgi-github commented 5 years ago

thanks mate, will try this approach for attributes as well.

sarah7777 commented 5 years ago

Hi, This page indicates that an empty string is a valid xs:string value https://www.oxygenxml.com/forum/topic1864.html And this validator allows an empty string for an xs:string type https://www.liquid-technologies.com/online-xsd-validator So I’m inclined to think it’s legal. Perhaps try your favourite validator? Kevin.

I'm experiencing this issue too. We have several xs:string elements in the schema with patterns that allow empty string and minOccurs="0" so it shouldn't be necessary to complete these fields on the form. However, they're generated with required="required" which causes validation to fail, preventing the form from being submitted without users attending to each of the affected fields.

This isn't actually a problem when a new set of data is entered as the field and tag are omitted by default, however after processing by another component we receive the XML data back with empty strings for each of these elements, which then become problematic string input fields when the data is edited in the HTML form. In order to make the form submit successfully, each one needs to be removed by clicking all the appropriate delete buttons.

I'm hoping that a simple XSLT change might prevent the required="required" attributes being generated for these fields when minOccurs="0"? We are currently using xsd2html2xml version 2 but unfortunately probably can't update to the latest very easily!

MichielCM commented 5 years ago

Hi, This page indicates that an empty string is a valid xs:string value https://www.oxygenxml.com/forum/topic1864.html And this validator allows an empty string for an xs:string type https://www.liquid-technologies.com/online-xsd-validator So I’m inclined to think it’s legal. Perhaps try your favourite validator? Kevin.

I'm experiencing this issue too. We have several xs:string elements in the schema with patterns that allow empty string and minOccurs="0" so it shouldn't be necessary to complete these fields on the form. However, they're generated with required="required" which causes validation to fail, preventing the form from being submitted without users attending to each of the affected fields.

This isn't actually a problem when a new set of data is entered as the field and tag are omitted by default, however after processing by another component we receive the XML data back with empty strings for each of these elements, which then become problematic string input fields when the data is edited in the HTML form. In order to make the form submit successfully, each one needs to be removed by clicking all the appropriate delete buttons.

I'm hoping that a simple XSLT change might prevent the required="required" attributes being generated for these fields when minOccurs="0"? We are currently using xsd2html2xml version 2 but unfortunately probably can't update to the latest very easily!

You can add a quick fix to the stylesheet: in the handle-simple-element template, wherever a 'required' attribute is added, add a check for the $min-occurs variable not being 0.

sarah7777 commented 5 years ago

You can add a quick fix to the stylesheet: in the handle-simple-element template, wherever a 'required' attribute is added, add a check for the $min-occurs variable not being 0.

Thanks for the prompt reply. I was able to make the changes successfully by taking that approach!