00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <sstream>
00022 #include "schemaparser/SchemaValidator.h"
00023 using namespace std;
00024
00025 namespace Schema {
00026
00027
00028
00029
00030
00031 SchemaValidator::SchemaValidator(const SchemaParser * sp,
00032 std::ostream& os)
00033 :ostr_(os),
00034 sParser_(sp)
00035 {
00036
00037
00038 }
00039
00040 SchemaValidator::~SchemaValidator()
00041 {
00042 }
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 TypeContainer *
00055 SchemaValidator::validate(XmlPullParser * xpp,
00056 int typeId,
00057 TypeContainer * ipTc)
00058 {
00059 TypeContainer *t=0;
00060
00061 try{
00062 string elemName = xpp->getName();
00063 const SchemaParser * s1Parser = sParser_;
00064 int typeId1= typeId;
00065
00066 if (!ipTc)
00067 t = new TypeContainer(typeId, sParser_);
00068 else
00069 t = ipTc;
00070
00071
00072
00073 if (t->getTypeId() != typeId)
00074 error("Fatal error ,container's type is not same as the validated type",xpp);
00075
00076
00077 if (typeId == Schema::XSD_SCHEMA){
00078
00079 SchemaParser * ssParser_ = new SchemaParser(xpp);
00080 if (!ssParser_->parseSchemaTag()){
00081
00082 delete ssParser_;
00083 return 0;
00084 }
00085 delete ssParser_;
00086 return t;
00087 }
00088
00089
00090 if (typeId == Schema::XSD_ANY){
00091
00092 xpp->skipSubTree();
00093 return t;
00094 }
00095
00096
00097 if (!sParser_->isBasicType(typeId)){
00098
00099 const XSDType * pType = sParser_->getType(typeId);
00100
00101 if (sParser_->isImported(pType->getNamespace())) {
00102
00103 sParser_ = sParser_->getImportedSchemaParser(pType->getNamespace());
00104 typeId = const_cast<SchemaParser*>(sParser_)->getTypeId(pType->getQname());
00105
00106 t->sParser_ = sParser_;
00107 t->typeId_ = (Schema::Type)typeId;
00108
00109 }
00110 }
00111
00112
00113 if (sParser_->getType(typeId) == 0
00114 || sParser_->getType(typeId)->isSimple()) {
00115
00116
00117 string val;
00118 xpp->nextToken();
00119 if (xpp->getEventType() == XmlPullParser::TEXT ||
00120 xpp->getEventType() == XmlPullParser::ENTITY_REF){
00121
00122 val = xpp->getText();
00123
00124 xpp->nextToken();
00125 while (xpp->getEventType() == XmlPullParser::ENTITY_REF ||
00126 xpp->getEventType() == XmlPullParser::TEXT){
00127
00128 val += xpp->getText();
00129 xpp->nextToken();
00130
00131 }
00132 validate(val, typeId, t,xpp);
00133 }
00134 else{
00135
00136 validate(val, typeId, t, xpp);
00137 }
00138 if (xpp->getEventType() == XmlPullParser::END_TAG)
00139 {
00140 if (xpp->getName() != elemName)
00141 error("Syntax error "+elemName,xpp);
00142 }
00143 else
00144 error("Expected a closing tag for " + elemName,xpp);
00145 }
00146 else {
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 const ComplexType *ct =
00160 static_cast<const ComplexType *>(sParser_->getType(typeId));
00161
00162 const ComplexType * bt = 0;
00163 TypeContainer * btCnt = 0;
00164 if (ct->getBaseTypeId()!=Schema::XSD_ANYTYPE) {
00165
00166 bt = static_cast<const ComplexType*>
00167 (sParser_->getType(ct->getBaseTypeId()));
00168 btCnt = t->getBaseTypeContainer(true);
00169 }
00170
00171 int attcnt = xpp->getAttributeCount();
00172
00173 for (int i = 0; i < attcnt; i++) {
00174
00175 std::string attName = xpp->getAttributeName(i);
00176 std::string attVal = xpp->getAttributeValue("", attName);
00177 std::string attNsp = xpp->getAttributeNamespace(i);
00178 if (!attNsp.empty() && attNsp != sParser_->getNamespace())
00179 continue;
00180
00181 const Attribute*at = 0;
00182 TypeContainer *atCnt = 0;
00183 at = ct->getAttribute(attName);
00184
00185 if (!at && bt){
00186 at = bt->getAttribute(attName);
00187 if (at)
00188 atCnt = btCnt->getAttributeContainer(attName, true);
00189 }
00190 else{
00191 atCnt = t->getAttributeContainer(attName, true);
00192 }
00193
00194 if (!at)
00195 error("Unknown attribute \"" + attName + "\"",xpp);
00196
00197 validate(attVal, at->getType(), atCnt, xpp);
00198 }
00199
00200
00201 checkAttributeOccurence(ct,xpp);
00202 if (bt)
00203 checkAttributeOccurence(bt,xpp);
00204
00205
00206 if (ct->getContentModel() == Schema::Simple)
00207 {
00208
00209
00210 string val;
00211 xpp->nextToken();
00212 if (xpp->getEventType() == xpp->TEXT){
00213 val = xpp->getText();
00214 validate(val, ct->getContentType(), t, xpp);
00215 xpp->nextTag();
00216 }
00217 else{
00218
00219 validate(val, ct->getContentType(), t, xpp);
00220 }
00221
00222 if (xpp->getEventType() == XmlPullParser::END_TAG)
00223 {
00224 if (xpp->getName() != elemName)
00225 error("Syntax error",xpp);
00226 }
00227 else
00228 error("Expected a closing tag for " + elemName,xpp);
00229 }
00230 else if (ct->getContentModel() == Schema::Complex){
00231
00232 ContentModel* cm=ct->getContents();
00233 ContentModel * bCm = 0;
00234 if (bt)
00235 bCm = bt ->getContents();
00236 if(cm)
00237 validateContentModel(xpp,
00238 cm,
00239 t->getChildContainer(cm,true),
00240 elemName,
00241 false,
00242 btCnt);
00243 else if (bCm)
00244 validateContentModel(xpp,
00245 bCm,
00246 btCnt->getChildContainer(bCm,true),
00247 elemName);
00248 else
00249 xpp->nextTag();
00250 }
00251 else{
00252
00253 }
00254 }
00255 typeId = typeId1;
00256 sParser_ = s1Parser;
00257 return t;
00258
00259 }catch (SchemaParserException spe){
00260
00261 if (!ipTc && t) delete t;
00262
00263 if(xpp){
00264
00265 spe.line=xpp->getLineNumber();
00266 spe.col=xpp->getColumnNumber();
00267 throw spe;
00268 }
00269 }
00270 return 0;
00271 }
00272
00273 TypeContainer*
00274 SchemaValidator::validateContentModel(XmlPullParser * xpp,
00275 ContentModel* cm,
00276 TypeContainer * ipTc,
00277 const string & elemName,
00278 bool nested,
00279 TypeContainer * btCnt)
00280 {
00281 ContentModel::ContentsIterator cit_b=cm->begin();
00282 ContentModel::ContentsIterator cit_e=cm->end();
00283 ContentModel::ContentsIterator ci=cit_e;
00284
00285 ContentModel::ContentsIterator bci;
00286 ContentModel * bCm=0;
00287
00288
00289 for (ci=cit_b;ci!=cit_e;ci++){
00290 if(ci->second==ContentModel::Particle)
00291 ci->first.e->nOccurrences=0;
00292 }
00293 ci=cit_b;
00294
00295 if (btCnt) {
00296 int t = btCnt->getTypeId();
00297 const ComplexType* ct = static_cast<const ComplexType*>(btCnt->schemaParser()->getType(t));
00298 bCm = ct->getContents();
00299 bci =bCm->begin();
00300 }
00301
00302 switch (cm->getCompositor()) {
00303
00304 case Schema::All:
00305 {
00306 do
00307 {
00308 if (!nested)
00309 xpp->nextTag();
00310 if (xpp->getEventType() == XmlPullParser::END_TAG)
00311 {
00312 if (xpp->getName() == elemName)
00313 break;
00314 while (xpp->getEventType() != XmlPullParser::START_TAG)
00315 xpp->nextTag();
00316 }
00317
00318
00319 if(!findElement(cit_b,cit_e,xpp->getName(),ci))
00320 error("Could not find element " +xpp->getName()+" in "+elemName,xpp);
00321 ci->first.e->nOccurrences++;
00322
00323 validate(xpp, ci->first.e->getType(),
00324 ipTc->getChildContainer(ci->first.e->getName(), true));
00325
00326 }
00327 while (true);
00328
00329
00330
00331
00332 for (ci=cit_b;ci!=cit_e;ci++){
00333 if(ci->second==ContentModel::Particle &&
00334 (ci->first.e->nOccurrences<ci->first.e->getMin()||
00335 ci->first.e->nOccurrences>ci->first.e->getMax()))
00336 error(ci->first.e->getName()+" did not meet occurrence constraints",xpp);
00337 }
00338
00339 break;
00340 }
00341 case Schema::Sequence:
00342 {
00343 do
00344 {
00345 if (!nested)
00346 xpp->nextTag();
00347
00348 if(xpp->getEventType() == XmlPullParser::END_TAG){
00349
00350 if (xpp->getName() == elemName)
00351 break;
00352 if(ci==cit_e)
00353 break;
00354
00355
00356 while ((xpp->getEventType() != XmlPullParser::START_TAG)&&
00357 ((xpp->getEventType() != XmlPullParser::END_TAG)||
00358 (xpp->getName() != elemName)))
00359 xpp->nextTag();
00360 }
00361
00362
00363
00364
00365 if(ci->second==ContentModel::Container){
00366
00367 if ((xpp->getEventType() == xpp->END_TAG)&&
00368 (xpp->getName() == elemName))
00369 break;
00370
00371 validateContentModel(xpp,ci->first.c,
00372 ipTc->getChildContainer(ci->first.c,true),
00373 elemName,true,btCnt);
00374 ci++;
00375 }
00376 else{
00377
00378
00379 if(cm->anyContents() ||
00380 findElement(ci,cit_e,xpp->getName(), ci)){
00381
00382 ci->first.e->nOccurrences++;
00383 validate(xpp,ci->first.e->getType(),
00384 ipTc->getChildContainer(ci->first.e->getName(), true));
00385
00386 }else if (bCm && (bCm->anyContents() ||
00387 findElement(bCm->begin(),bCm->end(),xpp->getName(), bci))){
00388
00389 TypeContainer * t = btCnt->getChildContainer(bCm,true);
00390 validate(xpp,bci->first.e->getType(),t->getChildContainer(bci->first.e->getName(),true));
00391
00392 } else {
00393
00394 error("Could not find element " +xpp->getName()+" in "+elemName,xpp);
00395 }
00396
00397 }
00398 }
00399 while (true);
00400
00401
00402
00403
00404 for (ci=cit_b;ci!=cit_e;ci++){
00405 if(ci->second==ContentModel::Particle &&
00406 (ci->first.e->nOccurrences<ci->first.e->getMin()||
00407 ci->first.e->nOccurrences>ci->first.e->getMax()))
00408 error(ci->first.e->getName()+" did not meet occurrence constraints",xpp);
00409 }
00410 break;
00411 }
00412 case Schema::Choice:
00413 {
00414
00415 if (!nested)
00416 xpp->nextTag();
00417
00418
00419 if(findElement(ci,cit_e,xpp->getName(), ci)) {
00420
00421 std::string choiceElem = xpp->getName();
00422 do {
00423
00424 ci->first.e->nOccurrences++;
00425 validate(xpp, ci->first.e->getType(),
00426 ipTc->getChildContainer(ci->first.e->getName(), true));
00427 xpp->nextTag();
00428 }while(xpp->getName() == choiceElem);
00429 xpp->prevTag();
00430 break;
00431 }
00432 else {
00433
00434 ci++;
00435 }
00436 if (ci->second == ContentModel::Container){
00437
00438 try {
00439 validateContentModel(xpp,ci->first.c,
00440 ipTc->getChildContainer(ci->first.c,true),
00441 elemName,true,btCnt);
00442 }
00443 catch (SchemaParserException spe){
00444
00445 ci++;
00446
00447 validateContentModel(xpp,ci->first.c,
00448 ipTc->getChildContainer(ci->first.c,true),
00449 elemName,true,btCnt);
00450 }
00451 }
00452 else{
00453
00454 error("Could not find element " +xpp->getName()+" in "+elemName,xpp);
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464 if(ci->second==ContentModel::Particle &&
00465 (ci->first.e->nOccurrences<ci->first.e->getMin()||
00466 ci->first.e->nOccurrences>ci->first.e->getMax()))
00467 error(ci->first.e->getName()+"did not meet occurrence constraints",xpp);
00468
00469 break;
00470 }
00471 }
00472
00473
00474
00475 for (ci=cit_b;ci!=cit_e;ci++){
00476
00477 if(ci->second==ContentModel::Particle)
00478 ci->first.e->nOccurrences=0;
00479 }
00480 return ipTc;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490 TypeContainer *
00491 SchemaValidator::validate(void* value ,
00492 int typeId,
00493 TypeContainer * ipTc,
00494 XmlPullParser * xpp)
00495 {
00496
00497 int basetype = sParser_->getBasicContentType(typeId);
00498
00499 const XSDType * pType = sParser_->getType(typeId);
00500 if (pType && !pType->isSimple()){
00501
00502 return 0;
00503 }
00504 const SimpleType *st = static_cast<const SimpleType*>(pType);
00505
00506
00507
00508
00509 if (!ipTc)
00510 ipTc = new TypeContainer(typeId, sParser_);
00511
00512 if (st && (st->isList() || st->isUnion())){
00513
00514 std::string val = *((std::string*)value);
00515 ipTc->setValue(val,validateListOrUnion(st,val,xpp));
00516 return ipTc;
00517 }
00518 switch (basetype)
00519 {
00520 case Schema::XSD_INTEGER:
00521 case Schema::XSD_INT:
00522 {
00523 int x= *((int*)value);
00524 if (!st) {
00525 ipTc->setValue(x);
00526 }
00527 else{
00528
00529 ipTc->setValue(x,st->isValidInt(x));
00530 }
00531 break;
00532 }
00533 case Schema::XSD_BYTE:
00534 {
00535 char c= *((char*)value);
00536 ipTc->setValue(c);
00537 }
00538 break;
00539 case Schema::XSD_FLOAT:
00540 {
00541 float f = *((float*)value);
00542 if (!st) {
00543
00544 ipTc->setValue(f);
00545
00546 }else{
00547
00548 ipTc->setValue(f,st->isValidFloat(f));
00549 }
00550 break;
00551 }
00552 case Schema::XSD_DOUBLE:
00553 case Schema::XSD_DECIMAL:
00554 {
00555 double db = *((double*)value);
00556 ipTc->setValue(db);
00557 }
00558 break;
00559 case Schema::XSD_LONG:
00560 {
00561 long l = *((long*)value);
00562 ipTc->setValue(l);
00563 }
00564 break;
00565 case Schema::XSD_POSINT:
00566 case Schema::XSD_ULONG:
00567 {
00568 unsigned long ul= *((unsigned long*)value);
00569 ipTc->setValue(ul);
00570 }
00571 break;
00572 case Schema::XSD_BOOLEAN:
00573 {
00574 bool b = *((bool*)value);
00575 ipTc->setValue(b);
00576 break;
00577 }
00578 case Schema::XSD_QNAME:
00579 {
00580 Qname q = *((Qname* )value);
00581 ipTc->setValue(q);
00582 }
00583 break;
00584 case Schema::XSD_STRING:
00585 default:
00586 {
00587 std::string val = *((std::string* )value);
00588 if (!st) {
00589
00590 ipTc->setValue(val);
00591 }
00592 else{
00593
00594 ipTc->setValue(val,st->isValidString(val));
00595 }
00596 }
00597 break;
00598 }
00599
00600 return ipTc;
00601 }
00602
00603
00604
00605
00606
00607
00608 TypeContainer *
00609 SchemaValidator::validate(const string & val,
00610 int typeId,
00611 TypeContainer *ipTc,
00612 XmlPullParser * xpp)
00613 {
00614
00615 int basetype = sParser_->getBasicContentType(typeId);
00616 if (basetype == Schema::XSD_INVALID) {
00617
00618 return 0;
00619 }
00620
00621 const XSDType * pType = sParser_->getType(typeId);
00622 if (pType &&
00623 !pType->isSimple() &&
00624 pType->getContentModel() != Schema::Simple){
00625
00626 return 0;
00627 }
00628
00629 if (pType && !pType->isSimple() &&
00630 pType->getContentModel() ==Schema::Simple) {
00631
00632
00633 const ComplexType * ct = static_cast<const ComplexType*>(pType);
00634 int contentType = ct->getContentType();
00635 return validate(val,contentType,ipTc,xpp);
00636
00637 }
00638 const SimpleType *st = static_cast<const SimpleType*>(pType);
00639
00640
00641
00642
00643 if (!ipTc)
00644 ipTc = new TypeContainer(typeId, sParser_);
00645 ipTc->setValAsString(val);
00646
00647 while(ipTc->isValueValid()){
00648
00649 extractSimpleType(val, basetype, ipTc, st, xpp);
00650
00651
00652 if(!st || (st && (st->isList() || st->isUnion()))){
00653
00654 break;
00655
00656
00657
00658 }
00659
00660 if (!sParser_->isBasicType(st->getBaseTypeId())){
00661
00662 st=static_cast<const SimpleType*>(sParser_->getType(st->getBaseTypeId()));
00663 }
00664 else{
00665 st = 0;
00666 }
00667 }
00668 return ipTc;
00669 }
00670
00671
00672 void
00673 SchemaValidator::extractSimpleType(const std::string & val,
00674 int basetype,
00675 TypeContainer * ipTc,
00676 const SimpleType * st,
00677 XmlPullParser * xpp)
00678 {
00679
00680 if (st && (st->isList() || st->isUnion())){
00681
00682 ipTc->setValue(val,validateListOrUnion(st,val,xpp));
00683 return;
00684 }
00685
00686 istringstream istr(val);
00687 int x;
00688 double db;
00689 long l;
00690 char c;
00691 unsigned long ul;
00692 float f;
00693
00694 switch (basetype)
00695 {
00696 case Schema::XSD_INTEGER:
00697 case Schema::XSD_INT:
00698 {
00699 istr >> x;
00700 if (!st) {
00701 ipTc->setValue(x,!istr.fail());
00702 }
00703 else{
00704
00705 ipTc->setValue(x,!istr.fail() && st->isValidInt(x));
00706 }
00707 break;
00708 }
00709 case Schema::XSD_BYTE:
00710 istr >> c;
00711 ipTc->setValue(c,!istr.fail());
00712 break;
00713 case Schema::XSD_FLOAT:
00714 {
00715 istr >> f;
00716 if (!st) {
00717 ipTc->setValue(f,!istr.fail());
00718 }else{
00719 ipTc->setValue(f,!istr.fail() && st->isValidFloat(f));
00720 }
00721 break;
00722 }
00723 case Schema::XSD_DOUBLE:
00724 case Schema::XSD_DECIMAL:
00725 istr >> db;
00726 ipTc->setValue(db,!istr.fail());
00727 break;
00728 case Schema::XSD_LONG:
00729 istr >> l;
00730 ipTc->setValue(l,!istr.fail());
00731 break;
00732 case Schema::XSD_POSINT:
00733 case Schema::XSD_ULONG:
00734 istr >> ul;
00735 ipTc->setValue(ul,!istr.fail());
00736 break;
00737 case Schema::XSD_BOOLEAN:
00738 {
00739
00740 if(val=="true" ||
00741 val=="yes" ||
00742 val=="1")
00743
00744 ipTc->setValue(true);
00745 else
00746 ipTc->setValue(false);
00747 break;
00748 }
00749 case Schema::XSD_QNAME:
00750 {
00751 Qname q(val);
00752 if (xpp)
00753 q.setNamespace(xpp->getNamespace(q.getPrefix()));
00754 ipTc->setValue(q);
00755 break;
00756 }
00757 case Schema::XSD_STRING:
00758 default:
00759 {
00760 if (!st) {
00761
00762 ipTc->setValue(val);
00763 }
00764 else{
00765 if (basetype == Schema::XSD_STRING)
00766 ipTc->setValue(val,st->isValidString(val));
00767 else
00768 ipTc->setValue(val);
00769 }
00770 }
00771 break;
00772 }
00773 }
00774
00775
00776
00777
00778
00779
00780 bool
00781 SchemaValidator::validateListOrUnion(const SimpleType* st,
00782 const std::string &val,
00783 XmlPullParser * xpp)
00784 {
00785 if (st->isList()){
00786
00787 size_t s = 0;
00788
00789 while(s < val.length()){
00790 while(val[s]==' ')s++;
00791 std::string t = val.substr(s,val.find(' ',s)-s);
00792 TypeContainer * tc = validate(t,st->getBaseTypeId(),0,xpp);
00793 if (!(tc && tc->isValueValid()))
00794 return false;
00795 s+=t.length()+1;
00796 }
00797 return true ;
00798
00799 }else if (st->isUnion()){
00800
00801 std::list<int>::const_iterator it= st->unionTypes()->begin();
00802 while (it!=st->unionTypes()->end()){
00803
00804 TypeContainer * tc = validate(val,*it,0,xpp);
00805
00806 if (tc && tc->isValueValid())
00807 return true;
00808 it++;
00809 }
00810 return false;
00811 }
00812 else{
00813 return false;
00814 }
00815 }
00816
00817
00818
00819
00820
00821
00822
00823
00824 bool
00825 SchemaValidator::findElement(ContentModel::ContentsIterator start,
00826 ContentModel::ContentsIterator end,
00827 std::string name,
00828 ContentModel::ContentsIterator & found)
00829 {
00830 for (ContentModel::ContentsIterator ci=start;
00831 ci!=end;
00832 ci++){
00833
00834 if(ci->second==ContentModel::Particle){
00835 #ifdef LOGGING
00836 std::cout<<"Looking for "<< name<<" found "<<ci->first.e->getName()<<std::endl;
00837 #endif
00838 if(ci->first.e->getName()==name ||
00839 ci->first.e->getName() == "*")
00840 {
00841 found=ci;
00842 return true;
00843 }
00844 }
00845 }
00846 return false;
00847 }
00848
00849 void SchemaValidator::error(const std::string& mesg,XmlPullParser* xpp)
00850 {
00851
00852 SchemaParserException spe(mesg + "\nError validating schema instance\n");
00853 if(xpp){
00854
00855 spe.line=xpp->getLineNumber();
00856 spe.col=xpp->getColumnNumber();
00857 }
00858 throw spe;
00859 }
00860
00861
00862 bool
00863 SchemaValidator::checkAttributeOccurence(const ComplexType* ct ,
00864 XmlPullParser* xpp)
00865 {
00866
00867 if (ct->getNumAttributes() > 0)
00868 {
00869 for (int i = 0; i < ct->getNumAttributes(); i++)
00870 {
00871 const Attribute*at = ct->getAttribute(i);
00872
00873
00874
00875
00876 string attVal = xpp->getAttributeValue("", at->getName());
00877 if (attVal.empty())
00878 {
00879 if (at->isRequired())
00880 error("Required attribute \"" + at->getName() +
00881 "\" missing or empty",xpp);
00882
00883 else
00884 continue;
00885 }
00886 }
00887 }
00888 return true;
00889 }
00890
00891
00892
00893 bool
00894 SchemaValidator::instance(const std::string& tag,
00895 Schema::Type type_id)
00896
00897 {
00898
00899
00900 std::string nsp = sParser_->getNamespace();
00901 xmlStream_ = new XmlSerializer(ostr_);
00902
00903 if (!nsp.empty())
00904 xmlStream_->setPrefix("s",nsp);
00905
00906 xmlStream_->setPrefix("xsi",Schema::SchemaInstaceUri);
00907 xmlStream_->startDocument("UTF-8",false);
00908
00909 return instance1(tag,type_id);
00910 }
00911
00912 bool
00913 SchemaValidator::instance1(const std::string &tag,
00914 Schema::Type type_id)
00915 {
00916
00917 std::string nsp = sParser_->getNamespace();
00918 static bool first = false;
00919 xmlStream_->startTag(nsp,tag);
00920 if (!first){
00921 xmlStream_->attribute("",
00922 "xmlns",
00923 nsp);
00924 first = true;
00925 }
00926
00927
00928
00929
00930
00931 const XSDType * pType = sParser_->getType(type_id);
00932
00933 if ( pType== 0 ||
00934 pType->isSimple()){
00935
00936 xmlStream_->text("");
00937
00938 }
00939 else {
00940
00941 const ComplexType * ct =
00942 static_cast<const ComplexType*>(pType);
00943
00944
00945 if (ct->getNumAttributes() > 0) {
00946
00947 for (int i = 0; i < ct->getNumAttributes(); i++) {
00948
00949 const Attribute*at = ct->getAttribute(i);
00950 xmlStream_->attribute(sParser_->getNamespace(),at->getName(),"");
00951 }
00952 }
00953
00954
00955 if (ct->getContentModel() == Schema::Simple) {
00956
00957 xmlStream_->text("");
00958 }
00959 else{
00960
00961 ContentModel* cm=ct->getContents();
00962 instanceCM(cm);
00963
00964 }
00965 }
00966 xmlStream_->endTag(nsp,tag);
00967 return true;
00968 }
00969
00970
00971
00972
00973 void
00974 SchemaValidator::instanceCM(ContentModel *cm)
00975
00976 {
00977
00978 ContentModel::ContentsIterator cit_b=cm->begin();
00979 ContentModel::ContentsIterator cit_e=cm->end();
00980 ContentModel::ContentsIterator ci=cit_b;
00981
00982 switch (cm->getCompositor())
00983 {
00984 case Schema::All:
00985 case Schema::Sequence:
00986 case Schema::Choice:
00987 {
00988
00989
00990
00991 for (ci=cit_b;ci!=cit_e;ci++){
00992
00993 if(ci->second==ContentModel::Particle &&
00994 ci->first.e->getMax() > 0){
00995
00996 const SchemaParser* s1Parser = sParser_;
00997 Schema::Type t=(Schema::Type)ci->first.e->getType();
00998
00999 if (!ci->first.e->getTypeNamespace().empty() &&
01000 sParser_->isImported(ci->first.e->getTypeNamespace()) &&
01001 sParser_->getNamespace() != ci->first.e->getTypeNamespace()) {
01002
01003
01004
01005 t = (Schema::Type)sParser_->getType(t)->getTypeId();
01006 sParser_ = sParser_->getImportedSchemaParser(ci->first.e->getTypeNamespace());
01007 }
01008
01009 instance1(ci->first.e->getName(),t);
01010 sParser_ = s1Parser;
01011 }
01012 else if (ci->second==ContentModel::Container) {
01013
01014
01015 instanceCM(ci->first.c);
01016
01017 }
01018 else if (ci->second==ContentModel::ParticleGroup){
01019
01020
01021 instanceCM(ci->first.g->getContents());
01022
01023 }
01024 }
01025 break;
01026 }
01027 }
01028 }
01029
01030 }
01031
01032
01033