schema validates
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sat, 31 Jul 2010 21:52:54 +0000 (21:52 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sat, 31 Jul 2010 21:52:54 +0000 (21:52 +0000)
changed bools to match XMLSchema xs:boolean type

git-svn-id: https://silmor.de/svn/softmagic/pack/trunk@582 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

13 files changed:
phpbase/object.php
qtbase/WHelper.cpp
qtbase/WHelper.h
qtbase/WObject.cpp
woc/php/phpclass.cpp
woc/php/phpstrans.cpp
woc/proc/procclass.cpp
woc/proc/procclass.h
woc/qt/qtclass.cpp
woc/qt/qtctrans.cpp
woc/soap/schemaout.cpp
woc/soap/schemaout.h
woc/soap/wob-base.xsd

index 28e350c..ea4a937 100644 (file)
@@ -31,6 +31,23 @@ class WObject {
                if(!method_exists($obj,"propertyArray"))return null;
                return $obj->propertyArray();
        }
+       
+       /**helper function for XML'ized objects that transforms XML boolean to PHP boolean*/
+       public static function fromXmlBoolean($str)
+       {
+               $s=strtolower(trim($str));
+               if(is_numeric($s))return ($s+0)!=0;
+               if($s=="true" || $s=="yes")return true;
+               else false;
+       }
+       /**helper function for XML'ized objects: it returns whether the string is a valid boolean*/
+       public static function isXmlBoolean($str)
+       {
+               $s=strtolower(trim($str));
+               if(is_numeric($s))return true;
+               if($s=="true" || $s=="yes" || $s=="false" || $s=="no")return true;
+               else false;
+       }
 };
 
 ?>
index 84ec965..cc7441f 100644 (file)
@@ -27,3 +27,13 @@ QList<QDomElement>WHelper::elementsByTagName(const QDomElement&root,QString tag)
        }
        return ret;
 }
+
+bool WHelper::str2bool(QString s)
+{
+       s=s.trimmed().toLower();
+       bool ok;
+       int i=s.toInt(&ok);
+       if(ok)return i!=0;
+       if(s=="true" || s=="yes")return true;
+       else return false;
+}
index f9e0f22..acd94a4 100644 (file)
@@ -24,6 +24,9 @@ class WHelper:public QObject
        protected:
                /**helper for de-serializers: returns direct child elements with given tag name (necessary because QDomElement::elementsByTagName traverses all children)*/
                static QList<QDomElement>elementsByTagName(const QDomElement&,QString);
+               
+               /**helper for XML decoding: transforms string to boolean*/
+               bool str2bool(QString s);
 };
 
 #endif
index 85ad4d2..10a7629 100644 (file)
@@ -10,4 +10,4 @@
 //
 //
 
-#include "WObject.h"
\ No newline at end of file
+#include "WObject.h"
index d7bb590..cc77fd4 100644 (file)
@@ -221,7 +221,7 @@ QString WocPHPClass::classPropertyListGetters(const WocClass&cls,QString prop)
        }else
        if(cls.propertyIsBool(prop)){
                code+="public function getstrlist_"+prop+"(){\n";
-               code+="\t$ret=array();\n\tforeach($this->prop_"+prop+" as $p)$ret[]=$p?\"yes\":\"no\";\n";
+               code+="\t$ret=array();\n\tforeach($this->prop_"+prop+" as $p)$ret[]=$p?\"true\":\"false\";\n";
                code+="\treturn $ret;\n}\n";
        }else
        if(cls.propertyIsEnum(prop)){
@@ -283,8 +283,8 @@ QString WocPHPClass::classPropertyListSetters(const WocClass&cls,QString prop)
        if(cls.propertyIsBool(prop)){
                code+="\t$prop=array();\n\tforeach($values as $value)\n";
                code+="\t\tif(is_bool($value))$prop[]=$value!=false;else\n";
-               code+="\t\tif($value==\"yes\")$prop[]=true;else\n";
-               code+="\t\tif($value==\"no\")$prop[]=false;else return false;\n";
+               code+="\t\tif(WObject::isXmlBoolean($value))$prop[]=WObject::fromXmlBoolean($value);else\n";
+               code+="\t\treturn false;\n";
                code+="\t$this->prop_"+prop+"=$prop;\n\treturn true;\n";
                acode+="\tif(is_bool($value)){\n";
                acode+="\t\t$this->prop_"+prop+"=$value!=false;\n\t\treturn true;\n\t}else return false;\n";
@@ -329,7 +329,7 @@ QString WocPHPClass::classPropertyScalarGetters(const WocClass&cls,QString prop)
                code+="public function getstr_"+prop+"(){return \"\".$this->prop_"+prop+";}\n";
        else
        if(cls.propertyIsBool(prop))
-               code+="public function getstr_"+prop+"(){return $this->prop_"+prop+"?\"yes\":\"no\";}\n";
+               code+="public function getstr_"+prop+"(){return $this->prop_"+prop+"?\"true\":\"false\";}\n";
        else
        if(cls.propertyIsEnum(prop)){
                code+="public function getstr_"+prop+"(){\n\tswitch($this->prop_"+prop+"){\n";
@@ -368,8 +368,8 @@ QString WocPHPClass::classPropertyScalarSetters(const WocClass&cls,QString prop)
        else
        if(cls.propertyIsBool(prop)){
                code+="\tif(is_bool($value))$this->prop_"+prop+"=$value!=false;else\n";
-               code+="\tif($value==\"yes\")$this->prop_"+prop+"=true;else\n";
-               code+="\tif($value==\"no\")$this->prop_"+prop+"=false;\n\telse return false;\n";
+               code+="\tif(WObject::isXmlBoolean($value))$this->prop_"+ prop+"=WObject::fromXmlBoolean($value);\n";
+               code+="\telse return false;\n";
                code+="\treturn true;\n";
        }else
        if(cls.propertyIsString(prop)||cls.propertyIsBlob(prop))
@@ -520,7 +520,7 @@ QString WocPHPClass::propertyToXml(const WocClass&cls,QString sl)
        if(cls.propertyIsAttribute(prop))
                return code+"\tif($p!==null)$root->setAttribute(\""+prop+"\",$this->getstr_"+prop+"());\n";
        //is it an element?
-       if(cls.propertyIsElement(prop))
+       if(cls.propertyIsSimpleElement(prop))
                return code+"\tif($p!==null)$root->appendChild($xml->createElement(\""+prop+"\",xq($this->getstr_"+prop+"())));\n";
        //is it a class?
        if(cls.propertyIsObject(prop))
index 4c4bd05..2a396b3 100644 (file)
@@ -88,9 +88,11 @@ QString WocPHPServerTransaction::trnInput(const WocTransaction&trn)
        for(int i=0;i<sl.size();i++){
                QString t=trn.inputType(sl[i]);
                if(trn.isAttributeType(t)){
-                       code+="\t\t$this->ainput[\""+sl[i]+"\"]=$root->getAttribute(\""+sl[i]+"\")";
+                       code+="\t\t$this->ainput[\""+sl[i]+"\"]=";
+                       if(trn.isBoolType(t))code+="WObject::fromXmlBoolean(";
+                       code+="$root->getAttribute(\""+sl[i]+"\")";
                        if(trn.isIntType(t))code+="+0";
-                       if(trn.isBoolType(t))code+="==\"yes\"";
+                       if(trn.isBoolType(t))code+=")";
                        code+=";\n";
                }else{
                        if(trn.isListType(t)){
@@ -101,9 +103,11 @@ QString WocPHPServerTransaction::trnInput(const WocTransaction&trn)
                                }else if(trn.isBlobType(t)){
                                        code+="\t\t\t$this->ainput[\""+sl[i]+"\"][]=base64_decode($el->textContent);\n";
                                }else{
-                                       code+="\t\t\t$this->ainput[\""+sl[i]+"\"][]=$el->textContent";
+                                       code+="\t\t\t$this->ainput[\""+sl[i]+"\"][]=";
+                                       if(trn.isBoolType(t))code+="WObject::fromXmlBoolean(";
+                                       code+="$el->textContent";
                                        if(trn.isIntType(t))code+="+0";
-                                       if(trn.isBoolType(t))code+="==\"yes\"";
+                                       if(trn.isBoolType(t))code+=")";
                                        code+=";\n";
                                }
                                code+="\t\t}\n";
index f656fef..b50edc7 100644 (file)
@@ -256,6 +256,7 @@ QString WocClass::propertyPlainType(QString p)const
 const QStringList WocClass::attrtypes=QStringList()<<"astring"<<"int"<<"int32"<<"int64"<<"bool";
 bool WocClass::propertyIsAttribute(QString p)const
 {
+       if(p.startsWith("List:"))return false;
        QString t=propertyPlainType(p);
        if(attrtypes.contains(t))return true;
        if(hasEnumType(t))return true;
@@ -263,12 +264,15 @@ bool WocClass::propertyIsAttribute(QString p)const
 }
 
 const QStringList WocClass::elemtypes=QStringList()<<"string"<<"blob";
-bool WocClass::propertyIsElement(QString p)const
+bool WocClass::propertyIsSimpleElement(QString p) const
 {
        QString t=propertyPlainType(p);
-       if(elemtypes.contains(t))return true;
-       if(hasEnumType(t))return true;
-       return false;
+       return elemtypes.contains(t);
+}
+
+bool WocClass::propertyIsElement(QString p)const
+{
+       return !propertyIsAttribute(p);
 }
 
 bool WocClass::propertyIsObject(QString p)const
index 3bad610..6d7b063 100644 (file)
@@ -60,6 +60,8 @@ class WocClass
                bool propertyIsAttribute(QString)const;
                /**returns whether this property is serialized as XML element*/
                bool propertyIsElement(QString)const;
+               /**returns whether this property is serialized as XML element, but not a class*/
+               bool propertyIsSimpleElement(QString)const;
                /**returns whether this property has an enum type*/
                bool propertyIsEnum(QString)const;
                /**returns whether the property is an object*/
index 0ff8f0c..7395609 100644 (file)
@@ -198,7 +198,7 @@ void WocQtClass::classDeserializer(const WocClass&cls,MFile&hdr,MFile&src,QStrin
                                scd+="\t\telse throw WDeserializerException(QCoreApplication::translate(\"WobTransaction\",\"Class '%1' property '%2' is integer list, but non-integer was found.\").arg(\""+cn+"\").arg(\""+k[i]+"\"));\n";
                        }else
                        if(cls.propertyIsBool(k[i])){
-                               scd+="\t\tadd"+k[i]+"(el.text()==\"yes\");\n";
+                               scd+="\t\tadd"+k[i]+"(str2bool(el.text()));\n";
                        }else
                        if(cls.propertyIsString(k[i])){
                                scd+="\t\tadd"+k[i]+"(el.text());\n";
@@ -233,7 +233,7 @@ void WocQtClass::classDeserializer(const WocClass&cls,MFile&hdr,MFile&src,QStrin
                                        scd+="\t\telse throw WDeserializerException(QCoreApplication::translate(\"WobTransaction\",\"Class '%1' property '%2' is integer, but non-integer was found.\").arg(\""+cn+"\").arg(\""+k[i]+"\"));\n";
                                }else
                                if(cls.propertyIsBool(k[i])){
-                                       scd+="\t\tset"+k[i]+"(root.attribute(\""+k[i]+"\")==\"yes\");\n";
+                                       scd+="\t\tset"+k[i]+"(str2bool(root.attribute(\""+k[i]+"\")));\n";
                                }else
                                if(cls.propertyIsString(k[i])){
                                        scd+="\t\tset"+k[i]+"(root.attribute(\""+k[i]+"\"));\n";
@@ -259,10 +259,10 @@ void WocQtClass::classDeserializer(const WocClass&cls,MFile&hdr,MFile&src,QStrin
                                        scd+="\t\tset"+k[i]+"(nl.at(0).toElement().text());\n";
                                }else
                                if(cls.propertyIsBlob(k[i])){
-                                       scd+="\t\tset"+k[i]+"(QByteArray::fromBase64(nl.at(0).toElement().text().toAscii()));\n";
+                                       scd+="\t\tset"+k[i]+ "(QByteArray::fromBase64(nl.at(0).toElement().text().toAscii()));\n";
                                }else
                                if(cls.propertyIsObject(k[i])){
-                                       scd+="\t\tset"+k[i]+"("+m_prefix+"O"+cls.propertyPlainType(k[i])+"(nl.at(0).toElement()));\n";
+                                       scd+="\t\tset"+k[i]+"("+ m_prefix+"O"+cls.propertyPlainType(k[i])+ "(nl.at(0).toElement()));\n";
                                }else{
                                        scd+="#error \"Internal Generator error.\"\n";
                                        qDebug("Error: unable to generate code for property %s of type %s.",k[i].toAscii().data(),cls.propertyType(k[i]).toAscii().data());
@@ -320,7 +320,7 @@ void WocQtClass::classSerializers(const WocClass&cls,MFile&hdr,MFile&src,QString
                        }else
                        if(cls.propertyIsBool(prop)){
                                scd+="\t\tQDomElement el=doc.createElement(\""+prop+"\");\n";
-                               scd+="\t\tel.appendChild(doc.createTextNode(mp_"+prop+"[i]?\"yes\":\"no\"));\n";
+                               scd+="\t\tel.appendChild(doc.createTextNode(mp_"+prop+"[i]?\"true\":\"false\"));\n";
                                scd+="\t\tr.appendChild(el);\n";
                        }else
                        if(cls.propertyIsBlob(prop)){
@@ -343,7 +343,7 @@ void WocQtClass::classSerializers(const WocClass&cls,MFile&hdr,MFile&src,QString
                        scd+="\tif(!mp_"+prop+".isNull()){\n";
                        if(cls.propertyIsAttribute(prop)){
                                if(cls.propertyIsBool(prop))
-                                       scd+="\t\tr.setAttribute(\""+prop+"\",mp_"+prop+".value()?\"yes\":\"no\");\n";
+                                       scd+="\t\tr.setAttribute(\""+prop+"\",mp_"+prop+".value()?\"true\":\"false\");\n";
                                else
                                        scd+="\t\tr.setAttribute(\""+prop+"\",mp_"+prop+".value());\n";
                        }else{
index e38b36e..9af83b7 100644 (file)
@@ -168,7 +168,7 @@ QString WocQtClientTransaction::trnInput(const WocTransaction&trn)
                if(trn.isAttributeType(t)){
                        code+="\troot.setAttribute(\""+sl[i]+"\",in_"+sl[i];
                        if(trn.isBoolType(t))
-                               code+="?\"yes\":\"no\"";
+                               code+="?\"true\":\"false\"";
                        code+=");\n";
                }else{
                        if(trn.isListType(t)){
@@ -183,7 +183,7 @@ QString WocQtClientTransaction::trnInput(const WocTransaction&trn)
                                                code+="QString::number(in_"+sl[i]+"[i])";
                                        else
                                        if(trn.isBoolType(t))
-                                               code+="in_"+sl[i]+"[i]?\"yes\":\"no\"";
+                                               code+="in_"+sl[i]+"[i]?\"true\":\"false\"";
                                        else
                                        if(trn.isBlobType(t))
                                                code+="in_"+sl[i]+".toBase64()";
@@ -237,9 +237,11 @@ QString WocQtClientTransaction::trnOutput(const WocTransaction&trn)
        for(int i=0;i<sl.size();i++){
                QString t=trn.outputType(sl[i]);
                if(trn.isAttributeType(t)){
-                       code+="\tout_"+sl[i]+"=root.attribute(\""+sl[i]+"\")";
+                       code+="\tout_"+sl[i]+"=";
+                       if(trn.isBoolType(t))code+="str2bool(";
+                       code+="root.attribute(\""+sl[i]+"\")";
                        if(trn.isIntType(t))code+=".toInt()";else
-                       if(trn.isBoolType(t))code+="==\"yes\"";
+                       if(trn.isBoolType(t))code+=")";
                        code+=";\n";
                }else{
                        code+="\tnl=elementsByTagName(root,\""+sl[i]+"\");\n";
@@ -250,7 +252,7 @@ QString WocQtClientTransaction::trnOutput(const WocTransaction&trn)
                                }else if(trn.isIntType(t)){
                                        code+="\t\tout_"+sl[i]+".append(nl.at(i).toElement().text().toInt());\n";
                                }else if(trn.isBoolType(t)){
-                                       code+="\t\tout_"+sl[i]+".append(nl.at(i).toElement().text()==\"yes\");\n";
+                                       code+="\t\tout_"+sl[i]+".append(str2bool(nl.at(i).toElement().text()));\n";
                                }else if(trn.isBlobType(t)){
                                        code+="\t\tout_"+sl[i]+".append(QByteArray::fromBase64(nl.at(i).toElement().text().toAscii()));\n";
                                }else{//can only be string
index 8273cff..77f9fdb 100644 (file)
@@ -15,6 +15,8 @@
 #include "mfile.h"
 
 #include <QDebug>
+#include <QDir>
+#include <QFileInfo>
 
 WocSchemaOut::WocSchemaOut(QString fname): WocOutput()
 {
@@ -24,6 +26,11 @@ WocSchemaOut::WocSchemaOut(QString fname): WocOutput()
        m_root=m_doc.createElementNS(woc->xmlSchemaNamespace(),"xs:schema");
        m_root.setAttribute("targetNamespace",woc->xmlProjectNamespace());
        m_root.setAttribute("xmlns",woc->xmlProjectNamespace());
+       m_root.setAttribute("elementFormDefault","qualified");
+       QDomElement el=m_doc.createElement("xs:import");
+       el.setAttribute("namespace",woc->xmlPackNamespace());
+       el.setAttribute("schemaLocation","wob-base.xsd");
+       m_root.appendChild(el);
 }
 
 void WocSchemaOut::finalize()
@@ -34,17 +41,62 @@ void WocSchemaOut::finalize()
        MFile fd(WocProcessor::instance()->baseDir()+"/"+m_name);
        fd.open(QIODevice::WriteOnly);
        fd.write(m_doc.toByteArray());
+       fd.close();
+       //copy 
+       QString s=QFileInfo(WocProcessor::instance()->baseDir()+"/"+m_name).dir().path();
+       MFile wfd(s+"/wob-base.xsd");
+       QFile bfd(":/wob-base.xsd");
+       wfd.open(QIODevice::WriteOnly);
+       bfd.open(QIODevice::ReadOnly);
+       wfd.write(bfd.readAll());
 }
 
 void WocSchemaOut::newClass(const WocClass& cls)
 {
        m_root.appendChild(m_doc.createComment("Class "+cls.name()));
+       //create enums
+       QStringList enl=cls.enumTypes();
+       for(int i=0;i<enl.size();i++){
+               QDomElement eel=m_doc.createElement("xs:simpleType");
+               eel.setAttribute("name","enum-"+cls.name()+"-"+enl[i]);
+               QDomElement rel=m_doc.createElement("xs:restriction");
+               rel.setAttribute("base","xs:NMTOKEN");
+               QList<WocEnum> vll=cls.enumValues(enl[i]);
+               for(int j=0;j<vll.size();j++){
+                       QDomElement nel=m_doc.createElement("xs:enumeration");
+                       nel.setAttribute("value",vll[j].name);
+                       rel.appendChild(nel);
+               }
+               eel.appendChild(rel);
+               m_root.appendChild(eel);
+       }
        //create type
        QDomElement cel=m_doc.createElement("xs:complexType");
        cel.setAttribute("name","class-"+cls.name());
+       QDomElement sel=m_doc.createElement("xs:sequence");
+       cel.appendChild(sel);
        //get properties
-       //create elements
-       //create attributes
+       QStringList prl=cls.propertyNames();
+       for(int i=0;i<prl.size();i++){
+               if(cls.propertyIsElement(prl[i])){
+                       //create elements
+                       QDomElement eel=m_doc.createElement("xs:element");
+                       eel.setAttribute("name",prl[i]);
+                       eel.setAttribute("type",schemaType(cls,prl[i]));
+                       eel.setAttribute("minOccurs","0");
+                       if(cls.propertyIsList(prl[i]))
+                               eel.setAttribute("maxOccurs","unbounded");
+                       sel.appendChild(eel);
+               }else{
+                       //create attributes
+                       QDomElement ael=m_doc.createElement("xs:attribute");
+                       ael.setAttribute("name",prl[i]);
+                       ael.setAttribute("type",schemaType(cls,prl[i]));
+                       ael.setAttribute("use","optional");
+                       cel.appendChild(ael);
+               }
+       }
+       
        //add to root
        m_root.appendChild(cel);
 }
@@ -54,11 +106,11 @@ void WocSchemaOut::newTransaction(const WocTransaction& trn)
        m_root.appendChild(m_doc.createComment("Transaction "+trn.name()));
        //create elements
        QDomElement tel=m_doc.createElement("xs:element");
-       tel.setAttribute("name",trn.name()+"-Request");
+       tel.setAttribute("name","WobRequest-"+trn.name());
        tel.setAttribute("type",trn.name()+"-Request");
        m_root.appendChild(tel);
        tel=m_doc.createElement("xs:element");
-       tel.setAttribute("name",trn.name()+"-Response");
+       tel.setAttribute("name","WobResponse-"+trn.name());
        tel.setAttribute("type",trn.name()+"-Response");
        m_root.appendChild(tel);
        
@@ -66,6 +118,7 @@ void WocSchemaOut::newTransaction(const WocTransaction& trn)
        tel=m_doc.createElement("xs:complexType");
        tel.setAttribute("name",trn.name()+"-Request");
        QDomElement wel=m_doc.createElement("xs:sequence");
+       tel.appendChild(wel);
        QStringList vars=trn.inputNames();
        for(int i=0;i<vars.size();i++){
                QString tp=trn.inputType(vars[i]);
@@ -85,12 +138,12 @@ void WocSchemaOut::newTransaction(const WocTransaction& trn)
                        wel.appendChild(el);
                }
        }
-       tel.appendChild(wel);
        m_root.appendChild(tel);
        //create type: rsp
        tel=m_doc.createElement("xs:complexType");
        tel.setAttribute("name",trn.name()+"-Response");
        wel=m_doc.createElement("xs:sequence");
+       tel.appendChild(wel);
        vars=trn.outputNames();
        for(int i=0;i<vars.size();i++){
                QString tp=trn.outputType(vars[i]);
@@ -110,7 +163,6 @@ void WocSchemaOut::newTransaction(const WocTransaction& trn)
                        wel.appendChild(el);
                }
        }
-       tel.appendChild(wel);
        m_root.appendChild(tel);
 }
 
@@ -122,10 +174,16 @@ QString WocSchemaOut::schemaType(QString tp)
        tp=WocTransaction::plainType(tp);
        if(WocTransaction::isObjectType(tp))return "class-"+tp;
        if(WocTransaction::isStringType(tp))return "xs:string";
-       if(WocTransaction::isBlobType(tp))return "xs:base64binary";
+       if(WocTransaction::isBlobType(tp))return "xs:base64Binary";
        if(WocTransaction::isBoolType(tp))return "xs:boolean";
        if(WocTransaction::isIntType(tp))return "xs:integer";
        //fallback, not pretty
        qDebug()<<"Warning: schema generator found unknown type"<<tp;
        return "xs:anysimpleType";
 }
+
+QString WocSchemaOut::schemaType(const WocClass& cls, QString prop)
+{
+       if(cls.propertyIsEnum(prop))return "enum-"+cls.name()+"-"+cls.propertyPlainType(prop);
+       return schemaType(cls.propertyType(prop));
+}
index 0b55f93..75753cc 100644 (file)
@@ -40,6 +40,8 @@ class WocSchemaOut:public WocOutput
                
                /**helper: returns the corresponding schema type for a WOB type*/
                QString schemaType(QString);
+               /**helper: returns the corresponding schema type for a WOB type*/
+               QString schemaType(const WocClass&,QString);
 };
 
 #endif
index 95cc574..9755df6 100644 (file)
@@ -2,24 +2,17 @@
 -->
 
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-           xmlns:wob="http://silmor.de/PACK/v0.5"
+           xmlns="http://silmor.de/PACK/v0.5"
            targetNamespace="http://silmor.de/PACK/v0.5" 
           elementFormDefault="qualified" >
 
   <!-- Error Reporting -->
-  <xs:element name="WobError" type="wob:WobError" />
+  <xs:element name="WobError" type="WobError" />
   <xs:complexType name="WobError" >
     <xs:simpleContent>
-         <xs:extension base="xs:string" />
+       <xs:extension base="xs:string" >
+         <xs:attribute name="type" type="xs:string" use="required" />
+       </xs:extension>
     </xs:simpleContent>
-    <xs:attribute name="type" type="xs:string" use="required" />
   </xs:complexType>
-
-</xs:schema>
-
-
-
-
-
-
-
+</xs:schema>
\ No newline at end of file