goetas / xsd2php

Convert XSD into PHP classes and serialize into XML (deserialize too)
149 stars 62 forks source link

Attributes aren't denoted - makes converting back to xml impossible #91

Closed marauxus closed 8 years ago

marauxus commented 9 years ago

I might just be using it incorrectly, but as far as I can tell, attributes are setup the same as fields, so when generating xml from the classes - the attributes are not done correctly.

Is there a way to automatically denote which properties are attributes so that JMS can properly generate the XML?

goetas commented 9 years ago

denoted

what do you mean? Do you have an example? (posting the command used to generate the classes/yaml metadata) I can not understand the issue.

marauxus commented 9 years ago

After attempting to paste an example, I see that it IS denoted (with " xml_attribute: true"). So my real problem is that the JMS Serializer seems to be ignoring that line and is spitting our the php object as another element instead of an attribute.

On Tue, Aug 18, 2015 at 3:51 PM, Asmir Mustafic notifications@github.com wrote:

denoted

what do you mean? Do you have an example? (posting the command used to generate the classes/yaml metadata) I can not understand the issue.

— Reply to this email directly or view it on GitHub https://github.com/goetas/xsd2php/issues/91#issuecomment-132347121.

marauxus commented 9 years ago

So this:

XSD:

/xsd:restriction /xsd:simpleType xsd:simpleContent /xsd:extension /xsd:simpleContent /xsd:complexType YML: PositiveWeightDimension: properties: __value: expose: true xml_value: true access_type: public_method accessor: getter: value setter: value type: float unitOfMeasure: expose: true access_type: public_method serialized_name: unitOfMeasure accessor: getter: getUnitOfMeasure setter: setUnitOfMeasure xml_attribute: true type: string is generating this: <__value>7 IN Whereas it should be generating this - or is the XSD written incorrectly?: 7 On Tue, Aug 18, 2015 at 3:57 PM, Joshua King king.joshua.daniel@gmail.com wrote: > After attempting to paste an example, I see that it IS denoted (with > " xml_attribute: true"). So my real problem is that the JMS Serializer > seems to be ignoring that line and is spitting our the php object as > another element instead of an attribute. > > On Tue, Aug 18, 2015 at 3:51 PM, Asmir Mustafic notifications@github.com > wrote: > > > denoted > > > > what do you mean? Do you have an example? (posting the command used to > > generate the classes/yaml metadata) I can not understand the issue. > > > > — > > Reply to this email directly or view it on GitHub > > https://github.com/goetas/xsd2php/issues/91#issuecomment-132347121.
goetas commented 9 years ago

something looks wrong with the yaml file... i have to check

3thanZ commented 8 years ago

Hi @goetas

Thanks for the great library. Really helpful.

I'm also facing the same problem as @marauxus. My XSD is as below:

<?xml version="1.0"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="jobsheet">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="hours_per_day" type="decimalTwoPrec" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:simpleType name="decimalTwoPrec">
    <xs:restriction base="xs:decimal">
        <xs:fractionDigits value="2" />
    </xs:restriction>
</xs:simpleType>

</xs:schema>

I then generate the PHP classes and JMS Serializer metadata using the commands:

./vendor/bin/xsd2php convert:php \
    prisma-xml-schema.xsd \
    --ns-map=';MyProject/Api/Models/' \
    --ns-dest='MyProject/Api/Models/;lib/Models'

./vendor/bin/xsd2php convert:jms-yaml \
    schema.xsd \
    --ns-map=';MyProject/Api/Models/' \
    --ns-dest='MyProject/Api/Models/;lib/Models/JMS'

The generated yaml for my schema is:

MyProject\Api\Models\Jobsheet:
    xml_root_name: jobsheet
    properties:
        hours_per_day:
            expose: true
            access_type: public_method
            serialized_name: hours_per_day
            accessor:
                getter: getHoursPerDay
                setter: setHoursPerDay
            type: float

The serialized object does not have the desired fractions. Could you kindly advise how to achieve the desired result?

goetas commented 8 years ago

Can you post also the generated php classes

3thanZ commented 8 years ago

Sure. It is as below:

<?php

namespace MyProject\Api\Models;

/**
 * Class representing Jobsheet
 */
class Jobsheet
{

    /**
     * @property float $hoursperday
     */
    private $hoursperday = null;

    /**
     * Gets as hoursperday
     *
     * @return float
     */
    public function getHoursperday()
    {
        return $this->hoursperday;
    }

    /**
     * Sets a new hoursperday
     *
     * @param float $hoursperday
     * @return self
     */
    public function setHoursperday($hoursperday)
    {
        $this->hoursperday = $hoursperday;
        return $this;
    }

}

?>
goetas commented 8 years ago

Do not understand the problem... all generated items looks good. What should be the desired output in your opinion?

3thanZ commented 8 years ago

I was looking for JMS Serializer to generate the XML with the element hours_per_day with 2 decimal points as defined in the simpleType decimalTwoPrec.

<jobsheet>
    <hours_per_day>8.00</hours_per_day>
</jobsheet>

Is this behaviour supported?

goetas commented 8 years ago

the serialization should work, but probably the <xs:fractionDigits value="2" /> rule will not be respected

3thanZ commented 8 years ago

Well that's the question. Is there a way to make it be respected? ;)

On Friday, 15 July 2016, Asmir Mustafic notifications@github.com wrote:

the serialization should work, but probably the <xs:fractionDigits value="2" /> rule will not be respected

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/goetas/xsd2php/issues/91#issuecomment-232937319, or mute the thread https://github.com/notifications/unsubscribe-auth/ABZoiLD6eb9ekZ8h-Ry5P0ZSs4HQQm-Vks5qV3rogaJpZM4Ftl7N .

Best regards, Ethan Siew Mobile: +6012 3822 032

goetas commented 8 years ago

You have to add an custom serializer for your type, and perform the seralization on your own

On 16 Jul 2016 12:42, "Ethan Siew" notifications@github.com wrote:

Well that's the question. Is there a way to make it be respected? ;)

On Friday, 15 July 2016, Asmir Mustafic notifications@github.com wrote:

the serialization should work, but probably the <xs:fractionDigits value="2" /> rule will not be respected

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/goetas/xsd2php/issues/91#issuecomment-232937319, or mute the thread < https://github.com/notifications/unsubscribe-auth/ABZoiLD6eb9ekZ8h-Ry5P0ZSs4HQQm-Vks5qV3rogaJpZM4Ftl7N

.

Best regards, Ethan Siew Mobile: +6012 3822 032

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/goetas/xsd2php/issues/91#issuecomment-233124550, or mute the thread https://github.com/notifications/unsubscribe-auth/AAvaJ4QysfHPf7qit5b63zgsya6tq6R_ks5qWLV6gaJpZM4Ftl7N .

3thanZ commented 8 years ago

Thanks. Will try that.

On Saturday, 16 July 2016, Asmir Mustafic notifications@github.com wrote:

You have to add an custom serializer for your type, and perform the seralization on your own

On 16 Jul 2016 12:42, "Ethan Siew" <notifications@github.com javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

Well that's the question. Is there a way to make it be respected? ;)

On Friday, 15 July 2016, Asmir Mustafic <notifications@github.com javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

the serialization should work, but probably the <xs:fractionDigits value="2" /> rule will not be respected

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/goetas/xsd2php/issues/91#issuecomment-232937319, or mute the thread <

https://github.com/notifications/unsubscribe-auth/ABZoiLD6eb9ekZ8h-Ry5P0ZSs4HQQm-Vks5qV3rogaJpZM4Ftl7N

.

Best regards, Ethan Siew Mobile: +6012 3822 032

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/goetas/xsd2php/issues/91#issuecomment-233124550, or mute the thread < https://github.com/notifications/unsubscribe-auth/AAvaJ4QysfHPf7qit5b63zgsya6tq6R_ks5qWLV6gaJpZM4Ftl7N

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/goetas/xsd2php/issues/91#issuecomment-233127486, or mute the thread https://github.com/notifications/unsubscribe-auth/ABZoiOlGuWLX-0JH2zWK55-VVG_EUk5jks5qWMpTgaJpZM4Ftl7N .

Best regards, Ethan Siew Mobile: +6012 3822 032

3thanZ commented 8 years ago

@goetas I managed to use a custom serializer to achieve the formatting that I need with one SimpleType. However, how do I pass map multiple SimpleTypes using the --alias-map argument?

I know for sure that the method below is incorrect, but what is the correct way?

./vendor/bin/xsd2php convert:jms-yaml \
    schema.xsd \
    --ns-map=';MyProject/Api/Models/' \
    --ns-dest='MyProject/Api/Models/;lib/Models/JMS' \
    --alias-map=';DecimalOnePrec;MyProject\Api\Models\JMS\DecimalOnePrecision' \
    --alias-map=';DecimalTwoPrecision;MyProject\Api\Models\JMS\DecimalTwoPrecision' \
    --alias-map=';DecimalFourPrecision;MyProject\Api\Models\JMS\DecimalFourPrecision'
3thanZ commented 8 years ago

It seems like specifying multiple --alias-map works as I noticed that all 3 aliases were picked up:

ethans-mbp:MyProject ethansiew$ ./regenerate-models.sh 
Namespaces:
    XML namepsace:  => PHP namepsace: MyProject/Api/Models/
Target directories:
    PHP namepsace: MyProject/Api/Models/ => Destination directory: lib/Models
Reading schema.xsd
 1/2 [==============>-------------]  50% Creating MyProject\Api\Models\Jobsheet... done.
 2/2 [============================] 100% Creating MyProject\Api\Models\Jobsheet\ExpensesAType... done.
Namespaces:
    XML namepsace:  => PHP namepsace: MyProject/Api/Models/
Target directories:
    PHP namepsace: MyProject/Api/Models/ => Destination directory: lib/Models
Aliases:
    XML Type: #DecimalOnePrec  => PHP Class: MyProject/Api/Models/\JMS\DecimalOnePrecision 
    XML Type: #DecimalTwoPrecision  => PHP Class: MyProject/Api/Models/\JMS\DecimalTwoPrecision 
    XML Type: #DecimalFourPrecision  => PHP Class: MyProject/Api/Models/\JMS\DecimalFourPrecision 
Reading schema.xsd
 1/2 [==============>-------------]  50% Item MyProject\Api\Models\Jobsheet\ExpensesAType... created source... saved source 792 bytes.
 2/2 [============================] 100% Item MyProject\Api\Models\Jobsheet... created source... saved source 710 bytes.
You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.org/xdebug
Generating autoload files

However, the generated yaml only recognized the DecimalOnePercision simple type.

My XSD:

<?xml version="1.0"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:simpleType name="DecimalOnePrec">
    <xs:restriction base="xs:decimal">
        <xs:fractionDigits value="1" />
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="DecimalTwoPrec">
    <xs:restriction base="xs:decimal">
        <xs:fractionDigits value="2" />
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="DecimalFourPrec">
    <xs:restriction base="xs:decimal">
        <xs:fractionDigits value="4" />
    </xs:restriction>
</xs:simpleType>

<xs:element name="jobsheet">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="jobsheet_number" type="xs:string" />
            <xs:element name="expenses" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType mixed="true">
                    <xs:sequence>
                        <xs:element name="units" type="DecimalOnePrec" />
                        <xs:element name="unit_cost" type="DecimalFourPrec" />
                        <xs:element name="total" type="DecimalTwoPrec" />
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

</xs:schema>

Command that I executed:

./vendor/bin/xsd2php convert:php \
    schema.xsd \
    --ns-map=';MyProject/Api/Models/' \
    --ns-dest='MyProject/Api/Models/;lib/Models'

./vendor/bin/xsd2php convert:jms-yaml \
    schema.xsd \
    --ns-map=';MyProject/Api/Models/' \
    --ns-dest='MyProject/Api/Models/;lib/Models/JMS' \
    --alias-map=';DecimalOnePrec;MyProject/Api/Models/JMS/DecimalOnePrecision' \
    --alias-map=';DecimalTwoPrecision;MyProject/Api/Models/JMS/DecimalTwoPrecision' \
    --alias-map=';DecimalFourPrecision;MyProject/Api/Models/JMS/DecimalFourPrecision'

Resulting YAML: jobsheet.yml (OK)

MyProject\Api\Models\Jobsheet:
    xml_root_name: jobsheet
    properties:
        jobsheetNumber:
            expose: true
            access_type: public_method
            serialized_name: jobsheet_number
            accessor:
                getter: getJobsheetNumber
                setter: setJobsheetNumber
            type: string
        expenses:
            expose: true
            access_type: public_method
            serialized_name: expenses
            accessor:
                getter: getExpenses
                setter: setExpenses
            xml_list:
                inline: true
                entry_name: expenses
            type: array<MyProject\Api\Models\Jobsheet\ExpensesAType>

jobsheet.ExpensesAType.yaml (NOT OK)

MyProject\Api\Models\Jobsheet\ExpensesAType:
    properties:
        units:
            expose: true
            access_type: public_method
            serialized_name: units
            accessor:
                getter: getUnits
                setter: setUnits
            type: MyProject/Api/Models/JMS/DecimalOnePrecision
        unitCost:
            expose: true
            access_type: public_method
            serialized_name: unit_cost
            accessor:
                getter: getUnitCost
                setter: setUnitCost
            type: float
        total:
            expose: true
            access_type: public_method
            serialized_name: total
            accessor:
                getter: getTotal
                setter: setTotal
            type: float
goetas commented 8 years ago

DecimalFourPrecision vs DecimalFourPrec DecimalTwoPrecision vs DecimalTwoPrec