NCBI C++ ToolKit
xsdparser.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: xsdparser.cpp 96770 2022-05-09 15:47:05Z gouriano $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Andrei Gourianov
27 *
28 * File Description:
29 * XML Schema parser
30 *
31 * ===========================================================================
32 */
33 
34 #include <ncbi_pch.hpp>
35 #include "exceptions.hpp"
36 #include "xsdparser.hpp"
37 #include "tokens.hpp"
38 #include "module.hpp"
39 #include "datatool.hpp"
40 #include <serial/error_codes.hpp>
41 
42 
43 #define NCBI_USE_ERRCODE_X Serial_Parsers
44 
46 
47 /////////////////////////////////////////////////////////////////////////////
48 // DTDParser
49 
51  : DTDParser(lexer)
52 {
54  m_ResolveTypes = false;
56 }
57 
59 {
60 }
61 
63 {
64  Reset();
65 }
66 
68 {
69  size_t lexerStackSize = m_StackLexer.size();
70  bool skipEof = false;
71  ParseHeader();
72  CopyComments(module.Comments());
73 
74  TToken tok;
75  int emb=0;
76  for (;;) {
77  tok = GetNextToken();
78  switch ( tok ) {
79  case K_INCLUDE:
80  ParseInclude();
81  break;
82  case K_ELEMENT:
83  ParseElementContent(0, emb);
84  break;
85  case K_ATTRIBUTE:
87  break;
88  case K_COMPLEXTYPE:
89  case K_SIMPLETYPE:
91  break;
92  case K_GROUP:
94  break;
95  case K_ATTPAIR:
96  break;
97  case T_EOF:
98  if (skipEof) {
99  skipEof = false;
100  break;
101  }
102  ParseError("Unexpected end-of-file", "keyword");
103  return;
104  case K_ENDOFTAG:
105  if (m_StackLexer.size() > lexerStackSize) {
106  skipEof = true;
107  break;
108  }
109  if (m_SrcType == eSchema) {
111  }
112  return;
113  case K_IMPORT:
114  ParseImport();
115  break;
116  case K_ATTRIBUTEGROUP:
118  break;
119  case K_ANNOTATION:
120  m_Comments = &(module.Comments());
121  ParseAnnotation();
122  break;
123  default:
124  ParseError("Invalid keyword", "keyword");
125  return;
126  }
127  }
128 }
129 
131 {
134  m_TargetNamespace.erase();
135  m_ElementFormDefault = false;
136  m_AttributeFormDefault = false;
137 }
138 
140 {
142  if (tok == T_EOF) {
143  return tok;
144  }
145  string data = NextToken().GetText();
146  string str1, str2, data2;
147 
148  m_Raw = data;
149  m_Element.erase();
150  m_ElementPrefix.erase();
151  m_Attribute.erase();
152  m_AttributePrefix.erase();
153  m_Value.erase();
154  m_ValuePrefix.erase();
155  if (tok == T_IDENTIFIER) {
157  } else if (tok == K_ATTPAIR || tok == K_XMLNS) {
158 // format is
159 // ns:attr="ns:value"
160  if (!NStr::SplitInTwo(data, "=", str1, data2)) {
161  ParseError("Unexpected data", "attribute (name=\"value\")");
162  }
165 // attribute
166  data = str1;
167  if (NStr::SplitInTwo(data, ":", str1, str2)) {
168  m_Attribute = str2;
169  m_AttributePrefix = str1;
170  } else if (tok == K_XMLNS) {
171  m_AttributePrefix = str1;
172  } else {
173  m_Attribute = str1;
174  }
175 // value
176  string::size_type first = 0, last = data2.length()-1;
177  if (data2.length() < 2 ||
178  (data2[first] != '\"' && data2[first] != '\'') ||
179  (data2[last] != '\"' && data2[last] != '\'') ) {
180  ParseError("Unexpected data", "attribute (name=\"value\")");
181  }
182  data = data2.substr(first+1, last - first - 1);
183  if (tok == K_XMLNS) {
187  m_PrefixToNamespace[m_Attribute] != data) {
188  ParseError("Unexpected xmlns data", "");
189  }
190  }
193  m_Value = data;
194  } else {
195  if (m_Attribute == "targetNamespace") {
196  m_Value = data;
197  } else {
198  if (NStr::SplitInTwo(data, ":", str1, str2)) {
199 // if (m_PrefixToNamespace.find(str1) == m_PrefixToNamespace.end()) {
200 // m_Value = data;
201 // } else {
202  m_Value = str2;
203  m_ValuePrefix = str1;
204 // }
205  } else {
206  m_Value = str1;
207  }
208  }
209  }
210  } else if (tok != K_ENDOFTAG && tok != K_CLOSING) {
211 // format is
212 // ns:element
213  if (NStr::SplitInTwo(data, ":", str1, str2)) {
214  m_Element = str2;
215  m_ElementPrefix = str1;
216  } else {
217  m_Element = str1;
218  }
221  }
222  }
223  ConsumeToken();
224  return tok;
225 }
226 
228 {
230  string ns(m_PrefixToNamespace[prefix]);
231  if (ns == "http://www.w3.org/2001/XMLSchema") {
232  return eSchemaNamespace;
233  } else if (ns == "http://schemas.xmlsoap.org/wsdl/") {
234  return eWsdlNamespace;
235  } else if (ns == "http://schemas.xmlsoap.org/wsdl/soap/") {
236  return eSoapNamespace;
237  }
238  }
239  return eUnknownNamespace;
240 }
241 
242 bool XSDParser::IsAttribute(const char* att) const
243 {
244  return NStr::strcmp(m_Attribute.c_str(),att) == 0;
245 }
246 
247 bool XSDParser::IsValue(const char* value) const
248 {
249  return NStr::strcmp(m_Value.c_str(),value) == 0;
250 }
251 
253 {
255  return false;
256  }
257  if (IsValue("string") || IsValue("token") ||
258  IsValue("normalizedString") ||
259  IsValue("duration") || IsValue("language") ||
260  IsValue("anyType") || IsValue("anyURI") ||
261  IsValue("Name") ||IsValue("NCName") || IsValue("QName") ||
262  IsValue("dateTime") || IsValue("time") || IsValue("date") ||
263  IsValue("gYearMonth") || IsValue("gYear") || IsValue("gMonthDay") || IsValue("gMonth") || IsValue("gDay") ||
264  IsValue("anySimpleType")) {
266  } else if (IsValue("double") || IsValue("float") || IsValue("decimal")) {
268  } else if (IsValue("boolean")) {
270  } else if (IsValue("integer") || IsValue("int")
271  || IsValue("short") || IsValue("byte")
272  || IsValue("negativeInteger") || IsValue("nonNegativeInteger")
273  || IsValue("positiveInteger") || IsValue("nonPositiveInteger")
274  || IsValue("unsignedInt") || IsValue("unsignedShort")
275  || IsValue("unsignedByte") ) {
277  } else if (IsValue("long") || IsValue("unsignedLong")) {
279  } else if (IsValue("hexBinary")) {
281  } else if (IsValue("base64Binary")) {
283  } else {
284  return false;
285  }
286  return true;
287 }
288 
290 {
292  return false;
293  }
294  if (IsValue("string") || IsValue("token") || IsValue("QName") ||
295  IsValue("language") ||
296  IsValue("anyType") || IsValue("anyURI") || IsValue("NCName") ||
297  IsValue("dateTime") || IsValue("time") || IsValue("date")) {
299  } else if (IsValue("ID")) {
300  attrib.SetType(DTDAttribute::eId);
301  } else if (IsValue("IDREF")) {
303  } else if (IsValue("IDREFS")) {
305  } else if (IsValue("NMTOKEN")) {
307  } else if (IsValue("NMTOKENS")) {
309  } else if (IsValue("ENTITY")) {
311  } else if (IsValue("ENTITIES")) {
313 
314  } else if (IsValue("boolean")) {
316  } else if (IsValue("int") || IsValue("integer")
317  || IsValue("short") || IsValue("byte")
318  || IsValue("negativeInteger") || IsValue("nonNegativeInteger")
319  || IsValue("positiveInteger") || IsValue("nonPositiveInteger")
320  || IsValue("unsignedInt") || IsValue("unsignedShort")
321  || IsValue("unsignedByte") ) {
323  } else if (IsValue("long") || IsValue("unsignedLong")) {
325  } else if (IsValue("float") || IsValue("double") || IsValue("decimal")) {
327  } else if (IsValue("base64Binary")) {
329  } else {
330  return false;
331  }
332  return true;
333 }
334 
336 {
337 // xml header
338  TToken tok = GetNextToken();
339  if (tok == K_XML) {
340  for ( ; tok != K_ENDOFTAG; tok=GetNextToken())
341  ;
342  tok = GetNextToken();
343  } else {
344  if (m_SrcType == eSchema) {
345  ERR_POST_X(4, GetLocation() << " XML declaration is missing");
346  }
347  }
348 // schema
349  if (tok != K_SCHEMA) {
350  ParseError("Unexpected token", "schema");
351  }
353  for ( tok = GetNextToken(); tok == K_ATTPAIR || tok == K_XMLNS; tok = GetNextToken()) {
354  if (tok == K_ATTPAIR) {
355  if (IsAttribute("targetNamespace")) {
357  } else if (IsAttribute("elementFormDefault")) {
358  m_ElementFormDefault = IsValue("qualified");
359  } else if (IsAttribute("attributeFormDefault")) {
360  m_AttributeFormDefault = IsValue("qualified");
361  }
362  }
363  }
365  if (tok != K_CLOSING) {
366  ParseError("tag closing");
367  }
368 }
369 
371 {
372  TToken tok;
373  string name;
374  for ( tok = GetNextToken(); tok == K_ATTPAIR || tok == K_XMLNS; tok = GetNextToken()) {
375  if (IsAttribute("schemaLocation")) {
376  name = m_Value;
377  }
378  }
379  if (tok != K_ENDOFTAG) {
380  ParseError("endoftag");
381  }
382  if (name.empty()) {
383  ParseError("schemaLocation");
384  }
385  string id(CreateEntityId(name, DTDEntity::eEntity));
386  DTDEntity& node = m_MapEntity[id];
387  if (node.GetName().empty()) {
388  node.SetName(name);
389  node.SetData(name);
390  node.SetExternal();
391  PushEntityLexer(id);
392  ParseHeader();
393  }
394 }
395 
397 {
398  bool import=true;
399  TToken tok = GetRawAttributeSet();
400  if (GetAttribute("namespace")) {
401  if (IsValue("http://www.w3.org/XML/1998/namespace") ||
402  (IsValue("//www.w3.org/XML/1998/namespace") && m_ValuePrefix == "http")) {
403  string name = "xml:lang";
404  m_MapAttribute[name].SetName(name);
405  m_MapAttribute[name].SetType(DTDAttribute::eString);
406  name = "xml:space";
407  m_MapAttribute[name].SetName(name);
408  m_MapAttribute[name].SetType(DTDAttribute::eString);
409  import=false;
410  }
411  }
412  if (import && GetAttribute("schemaLocation")) {
413  string name(m_Value);
414  string id(CreateEntityId(name, DTDEntity::eEntity));
415  DTDEntity& node = m_MapEntity[id];
416  if (node.GetName().empty()) {
417  node.SetName(name);
418  node.SetData(name);
419  node.SetExternal();
420  PushEntityLexer(id);
421  ParseHeader();
422  }
423  return;
424  }
425  if (tok == K_CLOSING) {
426  SkipContent();
427  }
428 }
429 
431 {
432  TToken tok;
433  if (GetRawAttributeSet() == K_CLOSING) {
434  for ( tok = GetNextToken(); tok != K_ENDOFTAG; tok=GetNextToken()) {
435  if (tok == K_DOCUMENTATION) {
437  } else if (tok == K_APPINFO) {
438  ParseAppInfo();
439  } else {
440  ParseError("documentation or appinfo");
441  }
442  }
443  }
444  m_ExpectLastComment = true;
445 }
446 
448 {
449  TToken tok = GetRawAttributeSet();
450  if (tok == K_ENDOFTAG) {
451  return;
452  }
453  if (tok == K_CLOSING) {
454  XSDLexer& l = dynamic_cast<XSDLexer&>(Lexer());
455  while (l.ProcessDocumentation())
456  ;
457  }
458  tok = GetNextToken();
459  if (tok != K_ENDOFTAG) {
460  ParseError("endoftag");
461  }
462  m_ExpectLastComment = true;
463 }
464 
466 {
467  TToken tok = GetRawAttributeSet();
468  if (tok == K_CLOSING) {
469  SkipContent();
470  }
471 }
472 
474 {
476  TToken tok;
477  for ( tok = GetNextToken(); tok == K_ATTPAIR || tok == K_XMLNS;
478  tok = GetNextToken()) {
479  if (tok == K_ATTPAIR ) {
481  }
482  }
483  return tok;
484 }
485 
486 bool XSDParser::GetAttribute(const string& att)
487 {
488  if (m_RawAttributes.find(att) != m_RawAttributes.end()) {
489  m_Attribute = att;
490  m_ValuePrefix = m_RawAttributes[att].first;
491  m_Value = m_RawAttributes[att].second;
492  return true;
493  }
494  m_Attribute.erase();
495  m_ValuePrefix.erase();
496  m_Value.erase();
497  return false;
498 }
499 
501 {
502  TToken tok;
503  bool eatEOT= false;
504  XSDLexer& l = dynamic_cast<XSDLexer&>(Lexer());
505  for ( tok = l.Skip(); ; tok = l.Skip()) {
506  if (tok == T_EOF) {
507  return;
508  }
509  ConsumeToken();
510  switch (tok) {
511  case K_ENDOFTAG:
512  if (!eatEOT) {
513  return;
514  }
515  break;
516  case K_CLOSING:
517  SkipContent();
518  break;
519  default:
520  case K_ELEMENT:
521  break;
522  }
523  eatEOT = tok == K_ELEMENT;
524  }
525 }
526 
528 {
529  DTDElement::EOccurrence occNew = occNow;
530  if (GetAttribute("minOccurs")) {
531  int m = NStr::StringToInt(m_Value);
532  if (m == 0) {
533  if (occNow == DTDElement::eOne) {
534  occNew = DTDElement::eZeroOrOne;
535  } else if (occNow == DTDElement::eOneOrMore) {
536  occNew = DTDElement::eZeroOrMore;
537  }
538  } else if (m > 1) {
540  occNew = DTDElement::eOneOrMore;
541  }
542  }
543  return occNew;
544 }
545 
547 {
548  DTDElement::EOccurrence occNew = occNow;
549  if (GetAttribute("maxOccurs")) {
550  int m = IsValue("unbounded") ? -1 : NStr::StringToInt(m_Value);
551  if (m == -1 || m > 1) {
552  if (m > 1) {
554  }
555  if (occNow == DTDElement::eOne) {
556  occNew = DTDElement::eOneOrMore;
557  } else if (occNow == DTDElement::eZeroOrOne) {
558  occNew = DTDElement::eZeroOrMore;
559  }
560  } else if (m == 0) {
561  occNew = DTDElement::eZero;
562  }
563  }
564  return occNew;
565 }
566 
568 {
569  TToken tok;
570  string name, value, name_space;
571  bool ref=false, named_type=false;
572  bool qualified = m_ElementFormDefault;
573  int line = Lexer().CurrentLine();
574 
575  tok = GetRawAttributeSet();
576 
577  if (GetAttribute("ref")) {
578  if (!owner) {
579  ParseError("ref attribute not allowed for root elements", "");
580  }
581  if (IsValue("schema") &&
583  name = CreateTmpEmbeddedName(owner->GetName(), emb);
584  DTDElement& elem = m_MapElement[name];
585  elem.SetEmbedded();
586  elem.SetName(m_Value);
587  elem.SetSourceLine(Lexer().CurrentLine());
589  ref=false;
590  } else {
591  ref=true;
592  name_space = m_ResolveTypes ? m_TargetNamespace :
594  name = m_Value + NStr::Replace(name_space, ":", "/");
595  }
596  }
597  if (GetAttribute("name")) {
598  ref=false;
599  name_space = m_TargetNamespace;
600  name = m_Value + NStr::Replace(name_space, ":", "/");;
601  if (owner) {
602  name = CreateTmpEmbeddedName(owner->GetName(), emb);
603  m_MapElement[name].SetEmbedded();
604  m_MapElement[name].SetNamed();
605  }
606  m_MapElement[name].SetName(m_Value);
607  m_MapElement[name].SetSourceLine(line);
608  SetCommentsIfEmpty(&(m_MapElement[name].Comments()));
609  }
610  if (GetAttribute("type")) {
611  if (!DefineElementType(m_MapElement[name])) {
612  m_MapElement[name].SetTypeName(
614  named_type = true;
615  }
616  }
617  if (owner && GetAttribute("form")) {
618  qualified = IsValue("qualified");
619  }
620  if (GetAttribute("default")) {
621  m_MapElement[name].SetDefault(m_Value);
622  }
623  if (GetAttribute("nillable")) {
624  m_MapElement[name].SetNillable(IsValue("true"));
625  }
626  if (owner && !name.empty()) {
627  owner->SetOccurrence(name, ParseMinOccurs( m_MapElement[name], owner->GetOccurrence(name)));
628  owner->SetOccurrence(name, ParseMaxOccurs( m_MapElement[name], owner->GetOccurrence(name)));
629  }
630  if (tok != K_CLOSING && tok != K_ENDOFTAG) {
631  ParseError("endoftag");
632  }
633  m_MapElement[name].SetNamespaceName(name_space);
634  m_MapElement[name].SetQualified(qualified);
635  bool hasContents = false;
636  if (tok == K_CLOSING) {
637  hasContents = ParseContent(m_MapElement[name]);
638  }
639  m_ExpectLastComment = true;
640  if (!ref && !named_type) {
641  named_type = NStr::StartsWith( m_MapElement[name].GetTypeName(), "type:");
642  if (!named_type) {
643  m_MapElement[name].SetTypeIfUnknown(
644  hasContents ? DTDElement::eEmpty : DTDElement::eString);
645  }
646  }
647  return name;
648 }
649 
650 string XSDParser::ParseGroup(DTDElement* owner, int emb)
651 {
652  string name;
653  TToken tok = GetRawAttributeSet();
654  if (GetAttribute("ref")) {
655 
657  name = CreateTmpEmbeddedName(owner->GetName(), emb);
658  DTDElement& node = m_MapElement[name];
659  node.SetEmbedded();
660  node.SetName(m_Value);
661  node.SetOccurrence( ParseMinOccurs( node, node.GetOccurrence()));
662  node.SetOccurrence( ParseMaxOccurs( node, node.GetOccurrence()));
663  node.SetQualified(owner->IsQualified());
664  SetCommentsIfEmpty(&(node.Comments()));
665 
666  bool already_there = find(m_StackLexerName.begin(), m_StackLexerName.end(), id) != m_StackLexerName.end();
667  if (m_ResolveTypes && !already_there) {
668  PushEntityLexer(id);
669  ParseGroupRef(node);
670  } else {
671  node.SetTypeName(id);
673  Lexer().FlushCommentsTo(node.Comments());
674  }
675  }
676  if (tok == K_CLOSING) {
677  ParseContent(m_MapElement[name]);
678  }
679  m_ExpectLastComment = true;
680  return name;
681 }
682 
684 {
685  if (GetNextToken() != K_GROUP) {
686  ParseError("group");
687  }
688  TToken tok = GetRawAttributeSet();
689  if (node.GetName().empty() && GetAttribute("name")) {
691  node.SetName(m_Value);
692  }
693  if (tok == K_CLOSING) {
694  ParseContent(node);
695  }
696  PopEntityLexer();
697 }
698 
699 bool XSDParser::ParseContent(DTDElement& node, bool extended /*=false*/)
700 {
701  DTDElement::EType curr_type;
702  int emb=0;
703  bool eatEOT= false;
704  bool hasContents= false;
705  TToken tok;
706  for ( tok=GetNextToken(); ; tok=GetNextToken()) {
707  emb = (int)node.GetContent().size();
708  if (tok != T_EOF &&
709  tok != K_ENDOFTAG &&
710  tok != K_ANNOTATION) {
711  hasContents= true;
712  }
713  switch (tok) {
714  case T_EOF:
715  return hasContents;
716  case K_ENDOFTAG:
717  if (eatEOT) {
718  eatEOT= false;
719  break;
720  }
721  FixEmbeddedNames(node);
722  return hasContents;
723  case K_COMPLEXTYPE:
724  ParseComplexType(node);
725  break;
726  case K_SIMPLETYPE:
727  ParseSimpleType(node);
728  break;
729  case K_SIMPLECONTENT:
730  ParseSimpleContent(node);
731  break;
732  case K_EXTENSION:
733  ParseExtension(node);
734  break;
735  case K_RESTRICTION:
736  ParseRestriction(node);
737  break;
738  case K_MINLENGTH:
739  case K_MAXLENGTH:
740  case K_LENGTH:
741  case K_PATTERN:
742  case K_INCMIN:
743  case K_EXCMIN:
744  case K_INCMAX:
745  case K_EXCMAX:
746  ParseFacet(node, tok);
747  break;
748  case K_ENUMERATION:
749  ParseEnumeration(node);
750  break;
751  case K_ATTRIBUTE:
752  ParseAttribute(node);
753  break;
754  case K_ATTRIBUTEGROUP:
755  ParseAttributeGroup(node);
756  break;
757  case K_ANY:
759  {
760  string name = CreateTmpEmbeddedName(node.GetName(), emb);
761  DTDElement& elem = m_MapElement[name];
762  elem.SetEmbedded();
763  elem.SetName(name);
764  elem.SetSourceLine(Lexer().CurrentLine());
766  elem.SetQualified(node.IsQualified());
767  ParseAny(elem);
768  AddElementContent(node,name);
769  }
770  break;
771  case K_SEQUENCE:
772  emb = (int)node.GetContent().size();
773  if (emb != 0 && extended) {
775  if (node.GetType() != DTDElement::eSequence) {
776  ParseError("sequence");
777  }
778  tok = GetRawAttributeSet();
779  eatEOT = true;
780  break;
781  }
782  curr_type = node.GetType();
783  if (curr_type == DTDElement::eUnknown ||
784  curr_type == DTDElement::eUnknownGroup ||
785  (m_ResolveTypes && curr_type == DTDElement::eEmpty)) {
787  ParseContainer(node);
788  if (node.GetContent().empty()) {
789  node.ResetType(curr_type);
790  }
791  } else {
792  string name = CreateTmpEmbeddedName(node.GetName(), emb);
793  DTDElement& elem = m_MapElement[name];
794  elem.SetEmbedded();
795  elem.SetName(name);
796  elem.SetSourceLine(Lexer().CurrentLine());
798  elem.SetQualified(node.IsQualified());
799  ParseContainer(elem);
800  AddElementContent(node,name);
801  }
802  break;
803  case K_CHOICE:
804  curr_type = node.GetType();
805  if (curr_type == DTDElement::eUnknown ||
806  curr_type == DTDElement::eUnknownGroup ||
807  (m_ResolveTypes && curr_type == DTDElement::eEmpty)) {
809  ParseContainer(node);
810  if (node.GetContent().empty()) {
811  node.ResetType(curr_type);
812  }
813  } else {
814  string name = CreateTmpEmbeddedName(node.GetName(), emb);
815  DTDElement& elem = m_MapElement[name];
816  elem.SetEmbedded();
817  elem.SetName(name);
818  elem.SetSourceLine(Lexer().CurrentLine());
820  elem.SetQualified(node.IsQualified());
821  ParseContainer(elem);
822  AddElementContent(node,name);
823  }
824  break;
825  case K_SET:
826  curr_type = node.GetType();
827  if (curr_type == DTDElement::eUnknown ||
828  curr_type == DTDElement::eUnknownGroup ||
829  (m_ResolveTypes && curr_type == DTDElement::eEmpty)) {
831  ParseContainer(node);
832  if (node.GetContent().empty()) {
833  node.ResetType(curr_type);
834  }
835  } else {
836  string name = CreateTmpEmbeddedName(node.GetName(), emb);
837  DTDElement& elem = m_MapElement[name];
838  elem.SetEmbedded();
839  elem.SetName(name);
840  elem.SetSourceLine(Lexer().CurrentLine());
842  elem.SetQualified(node.IsQualified());
843  ParseContainer(elem);
844  AddElementContent(node,name);
845  }
846  break;
847  case K_ELEMENT:
848  {
849  string name = ParseElementContent(&node,emb);
850  AddElementContent(node,name);
851  }
852  break;
853  case K_GROUP:
854  {
855  string name = ParseGroup(&node,emb);
856  AddElementContent(node,name);
857  }
858  break;
859  case K_ANNOTATION:
860  SetCommentsIfEmpty(&(node.Comments()));
861  ParseAnnotation();
862  break;
863  case K_UNION:
864  ParseUnion(node);
865  break;
866  case K_LIST:
867  ParseList(node);
868  break;
869  default:
870  for ( tok = GetNextToken(); tok == K_ATTPAIR || tok == K_XMLNS; tok = GetNextToken())
871  ;
872  if (tok == K_CLOSING) {
873  ParseContent(node);
874  }
875  break;
876  }
877  }
878  FixEmbeddedNames(node);
879  return hasContents;
880 }
881 
883 {
884  TToken tok = GetRawAttributeSet();
885  m_ExpectLastComment = true;
886  node.SetOccurrence( ParseMinOccurs( node, node.GetOccurrence()));
887  node.SetOccurrence( ParseMaxOccurs( node, node.GetOccurrence()));
888  if (tok == K_CLOSING) {
889  ParseContent(node);
890  }
891 }
892 
894 {
895  TToken tok = GetRawAttributeSet();
896  if (node.GetName().empty() && GetAttribute("name")) {
898  node.SetName(m_Value);
899  node.SetNamed();
900  }
901  if (GetAttribute("mixed")) {
902  if (IsValue("true")) {
903  string name(s_SpecialName);
904  AddElementContent(node,name);
905  }
906  }
907  if (tok == K_CLOSING) {
908  ParseContent(node);
909  }
910 }
911 
913 {
914  TToken tok = GetRawAttributeSet();
915  if (node.GetName().empty() && GetAttribute("name")) {
917  node.SetName(m_Value);
918  node.SetNamed();
919  }
920  if (tok == K_CLOSING) {
921  ParseContent(node);
922  }
923 }
924 
926 {
927  TToken tok = GetRawAttributeSet();
928  if (tok == K_CLOSING) {
929  ParseContent(node);
930  }
931 }
932 
934 {
935  TToken tok = GetRawAttributeSet();
936  bool extended=false;
937  if (GetAttribute("base")) {
938  if (!DefineElementType(node)) {
940  if (m_ResolveTypes) {
941  PushEntityLexer(id);
942  ParseContent(node);
943  extended=true;
944  } else {
945  node.SetTypeName(id);
946  }
947  }
948  }
949  if (tok == K_CLOSING) {
950  ParseContent(node, extended);
951  }
952 }
953 
955 {
956  TToken tok = GetRawAttributeSet();
957  bool extended=false;
958  if (GetAttribute("base")) {
959  if (!DefineElementType(node)) {
961  if (m_ResolveTypes) {
962  PushEntityLexer(id);
963  ParseContent(node);
964  extended=true;
965  } else {
966  node.SetTypeName(id);
967  }
968  }
969  }
970  if (tok == K_CLOSING) {
971  ParseContent(node,extended);
972  }
973 }
974 
976 {
977  TToken tok = GetRawAttributeSet();
978  if (GetAttribute("value")) {
979  switch (facet) {
980  case K_MINLENGTH:
982  break;
983  case K_MAXLENGTH:
985  break;
986  case K_LENGTH:
988  break;
989  case K_PATTERN:
991  break;
992  case K_INCMIN:
994  break;
995  case K_EXCMIN:
997  break;
998  case K_INCMAX:
1000  break;
1001  case K_EXCMAX:
1003  break;
1004  default:
1005  break;
1006  }
1007  }
1008  if (tok == K_CLOSING) {
1009  ParseContent(node);
1010  }
1011 }
1012 
1014 {
1015  TToken tok;
1016  if (DataTool().IsSetCodeGenerationStyle(CDataTool::eXmlElementEnums)) {
1017  tok = GetRawAttributeSet();
1018  if (node.GetType() == DTDElement::eInteger) {
1021  } else if (node.GetType() == DTDElement::eString) {
1023  node.SetType(DTDElement::eEnum);
1024  } else if (node.GetType() != DTDElement::eIntEnum && node.GetType() != DTDElement::eEnum) {
1025  ParseError("enum restriction not supported", "string or integer type");
1026  }
1027  if (GetAttribute("value")) {
1028  node.AddContent(m_Value);
1029  }
1030  return;
1031  }
1032  for ( tok = GetNextToken(); tok == K_ATTPAIR || tok == K_XMLNS; tok = GetNextToken())
1033  ;
1034  if (tok == K_CLOSING) {
1035  ParseContent(node);
1036  }
1037 }
1038 
1040 {
1041  DTDAttribute a;
1042  node.AddAttribute(a);
1043  DTDAttribute& att = node.GetNonconstAttributes().back();
1044  att.SetSourceLine(Lexer().CurrentLine());
1045  SetCommentsIfEmpty(&(att.Comments()));
1046  bool ref=false, named_type=false;
1047  bool qualified = m_AttributeFormDefault;
1048 
1049  TToken tok = GetRawAttributeSet();
1050  if (GetAttribute("ref")) {
1051  att.SetName(m_Value);
1052  if (m_ValuePrefix == "xml") {
1053  att.SetName(m_ValuePrefix + ":" + m_Value);
1054  }
1055  ref=true;
1056  }
1057  if (GetAttribute("name")) {
1058  att.SetName(m_Value);
1059  }
1060  if (GetAttribute("type")) {
1061  if (!DefineAttributeType(att)) {
1062  att.SetTypeName(
1064  named_type = true;
1065  }
1066  }
1067  if (GetAttribute("use")) {
1068  if (IsValue("required")) {
1070  } else if (IsValue("optional")) {
1072  } else if (IsValue("prohibited")) {
1074  }
1075  }
1076  if (GetAttribute("default")) {
1077  att.SetValue(m_Value);
1078  }
1079  if (GetAttribute("form")) {
1080  qualified = IsValue("qualified");
1081  }
1082  att.SetQualified(qualified);
1083  if (tok == K_CLOSING) {
1084  ParseContent(att);
1085  }
1086  if (!ref && !named_type) {
1088  }
1089  m_ExpectLastComment = true;
1090 }
1091 
1093 {
1094  TToken tok = GetRawAttributeSet();
1095  if (GetAttribute("ref")) {
1097  if (m_ResolveTypes) {
1098  PushEntityLexer(id);
1099  ParseAttributeGroupRef(node);
1100  } else {
1101  DTDAttribute a;
1102  a.SetType(DTDAttribute::eUnknownGroup);
1103  a.SetTypeName(id);
1105  node.AddAttribute(a);
1106  }
1107  }
1108  if (tok == K_CLOSING) {
1109  ParseContent(node);
1110  }
1111 }
1112 
1114 {
1115  if (GetNextToken() != K_ATTRIBUTEGROUP) {
1116  ParseError("attributeGroup");
1117  }
1118  if (GetRawAttributeSet() == K_CLOSING) {
1119  ParseContent(node);
1120  }
1121  PopEntityLexer();
1122 }
1123 
1125 {
1126  TToken tok = GetRawAttributeSet();
1127 #if 0
1128  if (GetAttribute("processContents")) {
1129  if (!IsValue("lax") && !IsValue("skip")) {
1130  ParseError("lax or skip");
1131  }
1132  }
1133 #endif
1134  node.SetOccurrence( ParseMinOccurs( node, node.GetOccurrence()));
1135  node.SetOccurrence( ParseMaxOccurs( node, node.GetOccurrence()));
1136  if (GetAttribute("namespace")) {
1137  node.SetNamespaceName(m_Value);
1138  }
1139  SetCommentsIfEmpty(&(node.Comments()));
1140  if (tok == K_CLOSING) {
1141  ParseContent(node);
1142  }
1143  m_ExpectLastComment = true;
1144 }
1145 
1147 {
1148  ERR_POST_X(9, Warning
1149  << GetLocation()
1150  << "Unsupported element type: union; in node "
1151  << node.GetName());
1153  TToken tok = GetRawAttributeSet();
1154  if (tok == K_CLOSING) {
1155 // ParseContent(node);
1156  SkipContent();
1157  }
1158  m_ExpectLastComment = true;
1159 }
1160 
1162 {
1163  ERR_POST_X(10, Warning
1164  << GetLocation()
1165  << "Unsupported element type: list; in node "
1166  << node.GetName());
1168  TToken tok = GetRawAttributeSet();
1169  if (tok == K_CLOSING) {
1170 // ParseContent(node);
1171  SkipContent();
1172  }
1173  m_ExpectLastComment = true;
1174 }
1175 
1177 {
1178  TToken tok = GetRawAttributeSet();
1179  string name;
1180  if (GetAttribute("ref")) {
1181  name = m_Value;
1182  }
1183  if (GetAttribute("name")) {
1184  name = m_Value;
1185  m_MapAttribute[name].SetName(name);
1186  SetCommentsIfEmpty(&(m_MapAttribute[name].Comments()));
1187  }
1188  if (GetAttribute("type")) {
1189  if (!DefineAttributeType(m_MapAttribute[name])) {
1190  m_MapAttribute[name].SetTypeName(
1192  }
1193  }
1194  m_MapAttribute[name].SetQualified(true);
1195  if (tok == K_CLOSING) {
1197  }
1198  m_ExpectLastComment = true;
1199  return name;
1200 }
1201 
1203 {
1204  TToken tok;
1205  for ( tok=GetNextToken(); tok != K_ENDOFTAG; tok=GetNextToken()) {
1206  switch (tok) {
1207  case T_EOF:
1208  return;
1209  case K_ENUMERATION:
1210  ParseEnumeration(att);
1211  break;
1212  case K_EXTENSION:
1213  ParseExtension(att);
1214  break;
1215  case K_RESTRICTION:
1216  ParseRestriction(att);
1217  break;
1218  case K_ANNOTATION:
1219  SetCommentsIfEmpty(&(att.Comments()));
1220  ParseAnnotation();
1221  break;
1222  case K_UNION:
1223  ParseUnion(att);
1224  break;
1225  case K_LIST:
1226  ParseList(att);
1227  break;
1228  default:
1229  tok = GetRawAttributeSet();
1230  if (tok == K_CLOSING) {
1231  ParseContent(att);
1232  }
1233  break;
1234  }
1235  }
1236 }
1237 
1239 {
1240  TToken tok = GetRawAttributeSet();
1241  if (GetAttribute("base")) {
1242  if (!DefineAttributeType(att)) {
1244  if (m_ResolveTypes) {
1245  PushEntityLexer(id);
1246  ParseContent(att);
1247  } else {
1248  att.SetTypeName(id);
1249  }
1250  }
1251  }
1252  if (tok == K_CLOSING) {
1253  ParseContent(att);
1254  }
1255 }
1256 
1258 {
1259  TToken tok = GetRawAttributeSet();
1260  if (GetAttribute("base")) {
1261  if (!DefineAttributeType(att)) {
1263  if (m_ResolveTypes) {
1264  PushEntityLexer(id);
1265  ParseContent(att);
1266  } else {
1267  att.SetTypeName(id);
1268  }
1269  }
1270  }
1271  if (tok == K_CLOSING) {
1272  ParseContent(att);
1273  }
1274 }
1275 
1277 // enumeration
1278 // http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration
1279 // actual value
1280 // http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#key-vv
1281 {
1282  TToken tok = GetRawAttributeSet();
1284  int id = 0;
1285  if (GetAttribute("intvalue")) {
1286  id = NStr::StringToInt(m_Value);
1288  }
1289  if (GetAttribute("value")) {
1290  string v(m_ValuePrefix);
1291  if (!v.empty()) {
1292  v += ':';
1293  }
1294  v += m_Value;
1296  att.AddEnumValue(v, Lexer().CurrentLine(), id);
1297  }
1298  if (tok == K_CLOSING) {
1299  ParseContent(att);
1300  }
1301 }
1302 
1304 {
1305  ERR_POST_X(9, Warning
1306  << GetLocation()
1307  << "Unsupported attribute type: union; in attribute "
1308  << att.GetName());
1310  TToken tok = GetRawAttributeSet();
1311  if (tok == K_CLOSING) {
1312 // ParseContent(att);
1313  SkipContent();
1314  }
1315 }
1316 
1318 {
1319  ERR_POST_X(10, Warning
1320  << GetLocation()
1321  << "Unsupported attribute type: list; in attribute "
1322  << att.GetName());
1324  TToken tok = GetRawAttributeSet();
1325  if (tok == K_CLOSING) {
1326 // ParseContent(att);
1327  SkipContent();
1328  }
1329 }
1330 
1331 string XSDParser::CreateTmpEmbeddedName(const string& name, int emb)
1332 {
1333  string emb_name(name);
1334  emb_name += "__emb#__";
1335  emb_name += NStr::IntToString(emb);
1336  while (m_EmbeddedNames.find(emb_name) != m_EmbeddedNames.end()) {
1337  emb_name += 'a';
1338  }
1339  m_EmbeddedNames.insert(emb_name);
1340  return emb_name;
1341 }
1342 
1344  const string& name, DTDEntity::EType type, const string* prefix)
1345 {
1346  string id;
1347  switch (type) {
1348  case DTDEntity::eType:
1349  id = string("type:") + name;
1350  break;
1351  case DTDEntity::eGroup:
1352  id = string("group:") + name;
1353  break;
1354  case DTDEntity::eAttGroup:
1355  id = string("attgroup:") + name;
1356  break;
1358  id = string("interface:") + name;
1359  break;
1361  id = string("binding:") + name;
1362  break;
1363  default:
1364  id = name;
1365  break;
1366  }
1367  if (prefix) {
1368  if (m_PrefixToNamespace.find(*prefix) == m_PrefixToNamespace.end() && !prefix->empty()) {
1369  string msg("Namespace prefix not defined: ");
1370  msg += *prefix;
1371  ParseError(msg.c_str(), "namespace declaration");
1372  }
1373  id += m_PrefixToNamespace[*prefix];
1374  } else {
1375  id += m_TargetNamespace;
1376  }
1377  return id;
1378 }
1379 
1381 {
1382  string id, name, data;
1383  TToken tok;
1384  data += "<" + m_Raw;
1385  for ( tok = GetNextToken(); tok == K_ATTPAIR || tok == K_XMLNS; tok = GetNextToken()) {
1386  data += " " + m_Raw;
1387  if (IsAttribute("name")) {
1388  name = m_Value;
1389  id = CreateEntityId(m_Value,type);
1390  m_MapEntity[id].SetName(name);
1391  }
1392  }
1393  data += m_Raw;
1394  if (name.empty()) {
1395  ParseError("name");
1396  }
1397  m_MapEntity[id].SetData(data);
1398  m_MapEntity[id].SetType(type);
1399  m_MapEntity[id].SetParseAttributes( m_TargetNamespace,
1402  Lexer().FlushComments();
1403  if (tok == K_CLOSING) {
1405  }
1406 }
1407 
1409 {
1410  string data = ent.GetData();
1411  string closing;
1412  TToken tok;
1413  CComments comments;
1414  bool doctag_open = false;
1415  for ( tok=GetNextToken(); tok != K_ENDOFTAG; tok=GetNextToken()) {
1416  if (tok == T_EOF) {
1417  break;
1418  }
1419  {
1420  CComments comm;
1421  Lexer().FlushCommentsTo(comm);
1422  if (!comm.Empty()) {
1424  comm.PrintDTD(buffer);
1426  data += closing;
1427  closing.erase();
1428  }
1429  if (!closing.empty()) {
1430  if (!comments.Empty()) {
1432  comments.Print(buffer, "", "\n", "");
1434  comments = CComments();
1435  }
1436  data += closing;
1437  closing.erase();
1438  doctag_open = false;
1439  }
1440  }
1441  if (tok == K_DOCUMENTATION) {
1442  if (!doctag_open) {
1443  data += "<" + m_Raw;
1444  }
1445  m_Comments = &comments;
1447  if (!doctag_open) {
1448  if (m_Raw == "/>") {
1449  data += "/>";
1450  closing.erase();
1451  } else {
1452  data += ">";
1453  closing = m_Raw;
1454  doctag_open = true;
1455  EndCommentBlock();
1456  }
1457  }
1458  } else if (tok == K_APPINFO) {
1459  ParseAppInfo();
1460  } else {
1461  data += "<" + m_Raw;
1462  for ( tok = GetNextToken(); tok == K_ATTPAIR || tok == K_XMLNS; tok = GetNextToken()) {
1463  data += " " + m_Raw;
1464  }
1465  data += m_Raw;
1466  }
1467  if (tok == K_CLOSING) {
1468  ent.SetData(data);
1469  ParseTypeDefinition(ent);
1470  data = ent.GetData();
1471  }
1472  }
1473  if (!comments.Empty()) {
1475  comments.Print(buffer, "", "\n", "");
1477  }
1478  data += closing;
1479  data += '\n';
1480  data += m_Raw;
1481  ent.SetData(data);
1482  m_Comments = 0;
1483 }
1484 
1486 {
1487  const CDataTool& app = DataTool();
1488  m_ResolveTypes = true;
1489  set<string> processed;
1490  bool found;
1491  do {
1492  found = false;
1494  for (i = m_MapElement.begin(); i != m_MapElement.end(); ++i) {
1495 
1496  DTDElement& node = i->second;
1497  if (!node.GetTypeName().empty()) {
1498  if ( node.GetType() == DTDElement::eUnknown) {
1499  found = true;
1500 // in rare cases of recursive type definition this node type can already be defined
1502  for (j = m_MapElement.begin(); j != m_MapElement.end(); ++j) {
1503  if (j->second.GetName() == node.GetName() &&
1504  j->second.GetTypeName() == node.GetTypeName() &&
1505  j->second.GetType() != DTDElement::eUnknown) {
1506  m_MapElement[i->first] = j->second;
1507  break;
1508  }
1509  }
1510  if (j != m_MapElement.end()) {
1511  break;
1512  }
1513  bool elementForm = m_ElementFormDefault;
1515  PushEntityLexer(node.GetTypeName());
1516  bool hasContents = ParseContent(node);
1518  } else {
1519  if (m_MapElement.find(node.GetTypeName()) != m_MapElement.end()) {
1521  } else {
1522  PushEntityLexer(node.GetTypeName());
1523  DTDElement item;
1524  bool hasContents = ParseContent(item);
1525  if (item.GetName().empty() ||
1526  (!item.GetName().empty() && item.GetName() == node.GetName()) ||
1527  item.GetNamespaceName() != node.GetNamespaceName()) {
1528  PushEntityLexer(node.GetTypeName());
1529  hasContents = ParseContent(node);
1531  } else {
1533  DTDElement::EType itype = item.GetType();
1534  bool pod = (itype >= DTDElement::eString) && (itype <= DTDElement::eBase64Binary);
1535  if (node.IsEmbedded() && pod &&
1536  item.GetContent().empty() && !item.HasAttributes() &&
1537  node.GetContent().empty() && !node.HasAttributes()) {
1538 // special case - plain std type
1539  node.SetType(item.GetType());
1540  for( const CMemberFacet& f : item.GetRestrictions()) {
1541  node.AddFacet(f);
1542  }
1543  } else {
1544  item.SetEmbedded(false);
1545  item.SetGlobalType(true);
1546  m_MapElement[node.GetTypeName()] = item;
1548  }
1549  }
1550  }
1551  }
1552 
1553 // Make local elements defined by means of global types global.
1554 // In fact, this is incorrect; also, in case of unqualified form default we must keep
1555 // such elements embedded, otherwise they will be treated as ns-qualified.
1556 
1557 // for us, this trick solves the problem of recursive type definitions:
1558 // local element A contains local element B, which contains local element A, etc.
1559 // the way it is now, code generator will simply crash.
1560 // The better solution would be to modify C++ code generation, of course.
1561 
1562 // as of 24may11, the code generator is modified.
1563 // BUT, the mistake is already made; we want to provide backward compatibility now.
1565  node.IsNamed() && node.IsEmbedded() && elementForm) {
1566 
1568  for (k = m_MapElement.begin(); k != m_MapElement.end(); ++k) {
1569  if (!k->second.IsEmbedded() && k->second.IsNamed() &&
1570  k->second.GetName() == node.GetName() &&
1571  k->second.GetTypeName() != node.GetTypeName()) {
1572  break;
1573  }
1574  }
1575  if (k == m_MapElement.end()) {
1576  node.SetEmbedded(false);
1577  }
1578  }
1579  } else if ( node.GetType() == DTDElement::eUnknownGroup) {
1580  found = true;
1582  node.GetOccurrence() == DTDElement::eZero) {
1583  PushEntityLexer(node.GetTypeName());
1584  ParseGroupRef(node);
1585  if (node.GetType() == DTDElement::eUnknownGroup) {
1587  }
1588  } else {
1589  if (m_MapElement.find(node.GetTypeName()) != m_MapElement.end()) {
1591  node.SetGlobalGroup(true);
1592  } else {
1593  PushEntityLexer(node.GetTypeName());
1594  DTDElement item;
1595  ParseGroupRef(item);
1596  if (item.GetName().empty()) {
1597  ParseError("Anonymous group", "group name");
1598  } else {
1599  item.SetEmbedded(false);
1600  item.SetNamed(false);
1601  item.SetGlobalGroup(true);
1602  m_MapElement[node.GetTypeName()] = item;
1604  if (occ == DTDElement::eOne || occ == DTDElement::eZeroOrOne) {
1606  node.SetGlobalGroup(true);
1607  } else if (occ == DTDElement::eOneOrMore || occ == DTDElement::eZeroOrMore) {
1609  node.SetName(item.GetName());
1611  string tmp2 = node.GetTypeName();
1612  node.SetOccurrence(tmp2, occ);
1613  node.SetGlobalGroup(true);
1614  AddElementContent(node, tmp2);
1615  }
1616  }
1617  }
1618  }
1619  }
1620  else if (processed.find(i->second.GetName() + i->second.GetNamespaceName())
1621  == processed.end()) {
1622  if (node.GetType() < DTDElement::eWsdlService) {
1623  PushEntityLexer(node.GetTypeName());
1624  ParseContent(node);
1625  }
1626  }
1627  processed.insert(i->second.GetName() + i->second.GetNamespaceName());
1628  } else {
1630  }
1631  }
1632  } while (found);
1633 
1634  do {
1635  found = false;
1637  for (i = m_MapElement.begin(); i != m_MapElement.end(); ++i) {
1638 
1639  DTDElement& node = i->second;
1640  if (node.HasAttributes()) {
1641  list<DTDAttribute>& atts = node.GetNonconstAttributes();
1642  list<DTDAttribute>::iterator a;
1643  for (a = atts.begin(); a != atts.end(); ++a) {
1644 
1645  if (!a->GetTypeName().empty()) {
1646  if ( a->GetType() == DTDAttribute::eUnknown) {
1647  found = true;
1648  PushEntityLexer(a->GetTypeName());
1649  ParseContent(*a);
1650  a->SetTypeIfUnknown(DTDAttribute::eString);
1651  } else if ( a->GetType() == DTDAttribute::eUnknownGroup) {
1652  found = true;
1653  PushEntityLexer(a->GetTypeName());
1654  atts.erase(a);
1655  ParseAttributeGroupRef(node);
1656  break;
1657  }
1658  } else {
1659  a->SetTypeIfUnknown(DTDAttribute::eString);
1660  }
1661  }
1662  }
1663  }
1664  } while (found);
1665 
1666  do {
1667  found = false;
1669  for (i = m_MapElement.begin(); i != m_MapElement.end(); ++i) {
1670 
1671  DTDElement& node = i->second;
1672  if (node.HasAttributes()) {
1673  list<DTDAttribute>& atts = node.GetNonconstAttributes();
1674  list<DTDAttribute>::iterator a;
1675  for (a = atts.begin(); a != atts.end(); ++a) {
1676  if (a->GetType() == DTDAttribute::eUnknown &&
1677  a->GetTypeName().empty() &&
1678  m_MapAttribute.find(a->GetName()) != m_MapAttribute.end()) {
1679  found = true;
1680  a->Merge(m_MapAttribute[a->GetName()]);
1681  }
1682  }
1683  }
1684  }
1685  } while (found);
1686 
1687  {
1689  for (i = m_MapElement.begin(); i != m_MapElement.end(); ++i) {
1690  i->second.MergeAttributes();
1691  }
1692  }
1693  m_ResolveTypes = false;
1694 }
1695 
1697 {
1703  if (ent && ent->GetType() != DTDEntity::eEntity) {
1707  }
1708 }
1710 {
1716 
1719  m_StackTargetNamespace.pop();
1722 }
1723 
1725 {
1727  BeginScope(ent);
1728  return ent;
1729 }
1730 
1732 {
1733  if (DTDParser::PopEntityLexer()) {
1734  EndScope();
1735  return true;
1736  }
1737  return false;
1738 }
1739 
1741  CNcbiIstream& in, const string& name, bool /*autoDelete*/ /*=true*/)
1742 {
1743  return new XSDEntityLexer(in,name);
1744 }
1745 
1746 #if defined(NCBI_DTDPARSER_TRACE)
1747 void XSDParser::PrintDocumentTree(void)
1748 {
1749  cout << " === Namespaces ===" << endl;
1751  for (i = m_PrefixToNamespace.begin(); i != m_PrefixToNamespace.end(); ++i) {
1752  cout << i->first << ": " << i->second << endl;
1753  }
1754 
1755  cout << " === Target namespace ===" << endl;
1756  cout << m_TargetNamespace << endl;
1757 
1758  cout << " === Element form default ===" << endl;
1759  cout << (m_ElementFormDefault ? "qualified" : "unqualified") << endl;
1760  cout << " === Attribute form default ===" << endl;
1761  cout << (m_AttributeFormDefault ? "qualified" : "unqualified") << endl;
1762  cout << endl;
1763 
1764  DTDParser::PrintDocumentTree();
1765 
1766  if (!m_MapAttribute.empty()) {
1767  cout << " === Standalone Attribute definitions ===" << endl;
1769  for (a= m_MapAttribute.begin(); a != m_MapAttribute.end(); ++ a) {
1770  PrintAttribute( a->second, false);
1771  }
1772  }
1773 }
1774 #endif
1775 
void FlushCommentsTo(CComments &comments)
Definition: alexer.cpp:218
int CurrentLine(void) const
Definition: alexer.hpp:77
void FlushComments(void)
Definition: alexer.cpp:213
const AbstractToken & NextToken(void) const
Definition: aparser.hpp:76
AbstractLexer & Lexer(void)
Definition: aparser.hpp:67
virtual void ParseError(const char *error, const char *expected, const AbstractToken &token)
Definition: aparser.cpp:54
void CopyComments(CComments &comments)
Definition: aparser.hpp:165
string GetText(void) const
Definition: atoken.hpp:49
CNcbiOstream & Print(CNcbiOstream &out, const string &before, const string &between, const string &after) const
Definition: comments.cpp:60
bool Empty(void) const
Definition: comments.hpp:89
CNcbiOstream & PrintDTD(CNcbiOstream &out, int flags=0) const
Definition: comments.cpp:121
@ eXmlElementEnums
Definition: datatool.hpp:66
@ eNoGlobalTypeClasses
Definition: datatool.hpp:63
@ ePreserveNestedElements
Definition: datatool.hpp:65
@ eNoGlobalGroupClasses
Definition: datatool.hpp:64
bool IsSetCodeGenerationStyle(ECodeGenerationStyle e) const
Definition: datatool.hpp:70
CComments & Comments(void)
Definition: module.hpp:119
CNcbiOstrstreamToString class helps convert CNcbiOstrstream to a string Sample usage:
Definition: ncbistre.hpp:802
void AddEnumValue(const string &value, int line, int id=0)
Definition: dtdaux.cpp:243
void SetName(const string &name)
Definition: dtdaux.cpp:189
void SetQualified(bool qualified)
Definition: dtdaux.hpp:177
void SetValueType(EValueType valueType)
Definition: dtdaux.cpp:225
void SetTypeIfUnknown(EType type)
Definition: dtdaux.cpp:203
void SetValue(const string &value)
Definition: dtdaux.cpp:234
void SetTypeName(const string &name)
Definition: dtdaux.cpp:215
void SetType(EType type)
Definition: dtdaux.cpp:198
const string & GetName(void) const
Definition: dtdaux.cpp:193
void SetSourceLine(int line)
Definition: dtdaux.cpp:179
CComments & Comments(void)
Definition: dtdaux.hpp:186
void SetName(const string &name)
Definition: dtdaux.cpp:339
const string & GetTypeName(void) const
Definition: dtdaux.cpp:392
void AddContent(const string &ref_name)
Definition: dtdaux.cpp:428
void SetTypeIfUnknown(EType type)
Definition: dtdaux.cpp:376
void SetTypeName(const string &name)
Definition: dtdaux.cpp:388
void AddFacet(const CMemberFacet &c)
Definition: dtdaux.hpp:355
bool IsEmbedded(void) const
Definition: dtdaux.cpp:466
void ResetType(EType type)
Definition: dtdaux.cpp:369
const list< CMemberFacet > & GetRestrictions(void) const
Definition: dtdaux.hpp:358
void SetSourceLine(int line)
Definition: dtdaux.cpp:330
void SetType(EType type)
Definition: dtdaux.cpp:359
void SetOccurrence(const string &ref_name, EOccurrence occ)
Definition: dtdaux.cpp:406
void SetGlobalType(bool def)
Definition: dtdaux.hpp:325
list< DTDAttribute > & GetNonconstAttributes(void)
Definition: dtdaux.cpp:497
bool IsNamed(void) const
Definition: dtdaux.cpp:354
@ eWsdlService
Definition: dtdaux.hpp:241
@ eBase64Binary
Definition: dtdaux.hpp:239
@ eOctetString
Definition: dtdaux.hpp:238
@ eUnknownGroup
Definition: dtdaux.hpp:222
EOccurrence GetOccurrence(const string &ref_name) const
Definition: dtdaux.cpp:410
@ eZeroOrOne
Definition: dtdaux.hpp:258
@ eZeroOrMore
Definition: dtdaux.hpp:257
@ eOneOrMore
Definition: dtdaux.hpp:256
CComments & AttribComments(void)
Definition: dtdaux.hpp:346
bool IsQualified(void) const
Definition: dtdaux.hpp:310
void SetQualified(bool qualified)
Definition: dtdaux.hpp:306
CComments & Comments(void)
Definition: dtdaux.hpp:338
void SetNamed(bool named=true)
Definition: dtdaux.cpp:350
bool HasAttributes(void) const
Definition: dtdaux.cpp:489
const string & GetName(void) const
Definition: dtdaux.cpp:346
const string & GetNamespaceName(void) const
Definition: dtdaux.cpp:539
void SetGlobalGroup(bool def)
Definition: dtdaux.hpp:331
const list< string > & GetContent(void) const
Definition: dtdaux.cpp:446
void AddAttribute(DTDAttribute &attrib)
Definition: dtdaux.cpp:485
void SetEmbedded(bool set=true)
Definition: dtdaux.cpp:462
void SetNamespaceName(const string &name)
Definition: dtdaux.cpp:534
EType GetType(void) const
Definition: dtdaux.cpp:383
void SetExternal(void)
Definition: dtdaux.cpp:81
const string & GetData(void) const
Definition: dtdaux.cpp:76
void GetParseAttributes(string &namespaceName, bool &elementForm, bool &attributeForm, map< string, string > &prefixToNamespace) const
Definition: dtdaux.cpp:108
@ eGroup
Definition: dtdaux.hpp:73
@ eEntity
Definition: dtdaux.hpp:71
@ eWsdlInterface
Definition: dtdaux.hpp:76
@ eWsdlBinding
Definition: dtdaux.hpp:77
@ eAttGroup
Definition: dtdaux.hpp:74
const string & GetName(void) const
Definition: dtdaux.cpp:67
EType GetType(void) const
Definition: dtdaux.cpp:93
void SetData(const string &data)
Definition: dtdaux.cpp:72
void SetName(const string &name)
Definition: dtdaux.cpp:63
virtual void EndCommentBlock(void) override
Definition: dtdparser.cpp:93
map< string, DTDEntity > m_MapEntity
Definition: dtdparser.hpp:149
string m_IdentifierText
Definition: dtdparser.hpp:153
void FixEmbeddedNames(DTDElement &node)
Definition: dtdparser.cpp:581
bool m_ExpectLastComment
Definition: dtdparser.hpp:158
map< string, DTDElement > m_MapElement
Definition: dtdparser.hpp:148
ESrcType m_SrcType
Definition: dtdparser.hpp:156
virtual bool PopEntityLexer(void)
Definition: dtdparser.cpp:725
list< string > m_StackLexerName
Definition: dtdparser.hpp:152
stack< AbstractLexer * > m_StackLexer
Definition: dtdparser.hpp:150
virtual string GetLocation(void) override
Definition: dtdparser.cpp:231
void ConsumeToken(void)
Definition: dtdparser.cpp:300
CComments * m_Comments
Definition: dtdparser.hpp:157
void SetCommentsIfEmpty(CComments *comments)
Definition: dtdparser.cpp:1563
virtual DTDEntity * PushEntityLexer(const string &name)
Definition: dtdparser.cpp:684
static const string & s_SpecialName
Definition: dtdparser.hpp:159
TToken GetNextToken(void)
Definition: dtdparser.cpp:247
void AddElementContent(DTDElement &node, string &id_name, char separator=0)
Definition: dtdparser.cpp:434
bool ProcessDocumentation(void)
Definition: xsdlexer.cpp:50
TToken Skip(void)
Definition: xsdlexer.cpp:105
string ParseAttributeContent(void)
Definition: xsdparser.cpp:1176
bool DefineAttributeType(DTDAttribute &att)
Definition: xsdparser.cpp:289
void ProcessNamedTypes(void)
Definition: xsdparser.cpp:1485
stack< bool > m_StackAttributeFormDefault
Definition: xsdparser.hpp:157
string m_ElementPrefix
Definition: xsdparser.hpp:137
stack< string > m_StackTargetNamespace
Definition: xsdparser.hpp:155
map< string, pair< string, string > > m_RawAttributes
Definition: xsdparser.hpp:143
virtual void BuildDocumentTree(CDataTypeModule &module) override
Definition: xsdparser.cpp:67
EElementNamespace GetElementNamespace(const string &prefix)
Definition: xsdparser.cpp:227
void ParseGroupRef(DTDElement &node)
Definition: xsdparser.cpp:683
void ParseSimpleType(DTDElement &node)
Definition: xsdparser.cpp:912
string m_AttributePrefix
Definition: xsdparser.hpp:139
virtual bool PopEntityLexer(void) override
Definition: xsdparser.cpp:1731
void ParseHeader(void)
Definition: xsdparser.cpp:335
string m_ValuePrefix
Definition: xsdparser.hpp:141
void ParseComplexType(DTDElement &node)
Definition: xsdparser.cpp:893
bool m_ElementFormDefault
Definition: xsdparser.hpp:149
map< string, string > m_PrefixToNamespace
Definition: xsdparser.hpp:145
string m_Element
Definition: xsdparser.hpp:136
void SkipContent()
Definition: xsdparser.cpp:500
void ParseUnion(DTDElement &node)
Definition: xsdparser.cpp:1146
virtual ~XSDParser(void)
Definition: xsdparser.cpp:58
DTDElement::EOccurrence ParseMinOccurs(DTDElement &node, DTDElement::EOccurrence occNow)
Definition: xsdparser.cpp:527
TToken GetNextToken(void)
Definition: xsdparser.cpp:139
void ParseImport(void)
Definition: xsdparser.cpp:396
string ParseElementContent(DTDElement *owner, int emb)
Definition: xsdparser.cpp:567
string CreateTmpEmbeddedName(const string &name, int emb)
Definition: xsdparser.cpp:1331
bool GetAttribute(const string &att)
Definition: xsdparser.cpp:486
bool DefineElementType(DTDElement &node)
Definition: xsdparser.cpp:252
void ParseAnnotation(void)
Definition: xsdparser.cpp:430
stack< bool > m_StackElementFormDefault
Definition: xsdparser.hpp:156
DTDElement::EOccurrence ParseMaxOccurs(DTDElement &node, DTDElement::EOccurrence occNow)
Definition: xsdparser.cpp:546
string m_Raw
Definition: xsdparser.hpp:135
string m_TargetNamespace
Definition: xsdparser.hpp:148
stack< map< string, string > > m_StackPrefixToNamespace
Definition: xsdparser.hpp:153
void ParseDocumentation(void)
Definition: xsdparser.cpp:447
void ParseAttribute(DTDElement &node)
Definition: xsdparser.cpp:1039
void ParseSimpleContent(DTDElement &node)
Definition: xsdparser.cpp:925
XSDParser(XSDLexer &lexer)
Definition: xsdparser.cpp:50
string m_Value
Definition: xsdparser.hpp:140
virtual DTDEntity * PushEntityLexer(const string &name) override
Definition: xsdparser.cpp:1724
void Reset(void)
Definition: xsdparser.cpp:130
stack< map< string, string > > m_StackNamespaceToPrefix
Definition: xsdparser.hpp:154
void ParseExtension(DTDElement &node)
Definition: xsdparser.cpp:933
string m_Attribute
Definition: xsdparser.hpp:138
void ParseAttributeGroup(DTDElement &node)
Definition: xsdparser.cpp:1092
void ParseTypeDefinition(DTDEntity &ent)
Definition: xsdparser.cpp:1408
bool IsAttribute(const char *att) const
Definition: xsdparser.cpp:242
void CreateTypeDefinition(DTDEntity::EType type)
Definition: xsdparser.cpp:1380
map< string, string > m_NamespaceToPrefix
Definition: xsdparser.hpp:146
bool m_EnableNamespaceRedefinition
Definition: xsdparser.hpp:160
@ eWsdlNamespace
Definition: xsdparser.hpp:56
@ eUnknownNamespace
Definition: xsdparser.hpp:54
@ eSchemaNamespace
Definition: xsdparser.hpp:55
@ eSoapNamespace
Definition: xsdparser.hpp:57
void ParseAny(DTDElement &node)
Definition: xsdparser.cpp:1124
string ParseGroup(DTDElement *owner, int emb)
Definition: xsdparser.cpp:650
string CreateEntityId(const string &name, DTDEntity::EType type, const string *prefix=NULL)
Definition: xsdparser.cpp:1343
void EndScope(void)
Definition: xsdparser.cpp:1709
void BeginScope(DTDEntity *ent)
Definition: xsdparser.cpp:1696
void ParseList(DTDElement &node)
Definition: xsdparser.cpp:1161
void ParseAttributeGroupRef(DTDElement &node)
Definition: xsdparser.cpp:1113
virtual AbstractLexer * CreateEntityLexer(CNcbiIstream &in, const string &name, bool autoDelete=true) override
Definition: xsdparser.cpp:1740
map< string, DTDAttribute > m_MapAttribute
Definition: xsdparser.hpp:147
virtual void BeginDocumentTree(void) override
Definition: xsdparser.cpp:62
TToken GetRawAttributeSet(void)
Definition: xsdparser.cpp:473
bool IsValue(const char *value) const
Definition: xsdparser.cpp:247
bool m_AttributeFormDefault
Definition: xsdparser.hpp:150
bool m_ResolveTypes
Definition: xsdparser.hpp:159
set< string > m_EmbeddedNames
Definition: xsdparser.hpp:158
void ParseFacet(DTDElement &node, TToken tok)
Definition: xsdparser.cpp:975
void ParseContainer(DTDElement &node)
Definition: xsdparser.cpp:882
void ParseRestriction(DTDElement &node)
Definition: xsdparser.cpp:954
void ParseEnumeration(DTDElement &node)
Definition: xsdparser.cpp:1013
void ParseInclude(void)
Definition: xsdparser.cpp:370
bool ParseContent(DTDElement &node, bool extended=false)
Definition: xsdparser.cpp:699
void ParseAppInfo(void)
Definition: xsdparser.cpp:465
const_iterator begin() const
Definition: map.hpp:151
const_iterator end() const
Definition: map.hpp:152
bool empty() const
Definition: map.hpp:149
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
const_iterator find(const key_type &key) const
Definition: set.hpp:137
const_iterator end() const
Definition: set.hpp:136
char value[7]
Definition: config.c:431
CDataTool & DataTool(void)
Definition: datatool.hpp:90
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static DLIST_TYPE *DLIST_NAME() last(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:51
string
Definition: cgiapp.hpp:687
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
Definition: ncbidiag.hpp:550
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
static int strcmp(const char *s1, const char *s2)
String compare.
Definition: ncbistr.hpp:5207
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string (in-place)
Definition: ncbistr.cpp:3197
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5083
static string & Replace(const string &src, const string &search, const string &replace, string &dst, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3310
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5411
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
Definition: ncbistr.cpp:3550
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
Definition of all error codes used in serial libraries (xser.lib, xcser.lib).
int i
constexpr bool empty(list< Ts... >) noexcept
unsigned int a
Definition: ncbi_localip.c:102
std::istream & in(std::istream &in_, double &x_)
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
static const char * prefix[]
Definition: pcregrep.c:405
static pcre_uint8 * buffer
Definition: pcretest.c:1051
Definition: type.c:6
TToken
Definition: tokens.hpp:38
@ K_XML
Definition: tokens.hpp:125
@ T_IDENTIFIER
Definition: tokens.hpp:42
@ K_GROUP
Definition: tokens.hpp:140
@ K_INCMIN
Definition: tokens.hpp:148
@ K_DOCUMENTATION
Definition: tokens.hpp:138
@ K_CHOICE
Definition: tokens.hpp:71
@ K_APPINFO
Definition: tokens.hpp:141
@ K_EXTENSION
Definition: tokens.hpp:133
@ K_CLOSING
Definition: tokens.hpp:123
@ K_UNION
Definition: tokens.hpp:142
@ K_COMPLEXTYPE
Definition: tokens.hpp:129
@ K_RESTRICTION
Definition: tokens.hpp:134
@ K_MAXLENGTH
Definition: tokens.hpp:145
@ K_MINLENGTH
Definition: tokens.hpp:144
@ K_ANY
Definition: tokens.hpp:101
@ K_XMLNS
Definition: tokens.hpp:128
@ K_ENDOFTAG
Definition: tokens.hpp:124
@ K_SEQUENCE
Definition: tokens.hpp:69
@ K_ATTPAIR
Definition: tokens.hpp:127
@ K_EXCMAX
Definition: tokens.hpp:151
@ K_SIMPLETYPE
Definition: tokens.hpp:131
@ T_EOF
Definition: tokens.hpp:39
@ K_ANNOTATION
Definition: tokens.hpp:137
@ K_SCHEMA
Definition: tokens.hpp:126
@ K_PATTERN
Definition: tokens.hpp:147
@ K_ATTRIBUTEGROUP
Definition: tokens.hpp:139
@ K_INCMAX
Definition: tokens.hpp:150
@ K_ENUMERATION
Definition: tokens.hpp:136
@ K_LENGTH
Definition: tokens.hpp:146
@ K_EXCMIN
Definition: tokens.hpp:149
@ K_LIST
Definition: tokens.hpp:143
@ K_SIMPLECONTENT
Definition: tokens.hpp:132
@ K_IMPORT
Definition: tokens.hpp:121
@ K_ELEMENT
Definition: tokens.hpp:97
@ K_ATTRIBUTE
Definition: tokens.hpp:135
@ K_SET
Definition: tokens.hpp:68
@ K_INCLUDE
Definition: tokens.hpp:119
Modified on Tue Dec 05 02:08:49 2023 by modify_doxy.py rev. 669887