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