--- /dev/null
+/*******************************************************************************
+* Copyright (c) 2000-2016 Ericsson Telecom AB
+*
+* XSD to TTCN-3 Translator version: CRL 113 200/5 R4A
+*
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*******************************************************************************/
+//
+// File: http_www_example_org_2001_XMLSchema_e.ttcn
+// Description:
+// References:
+// Rev:
+// Prodnr:
+// Updated: Mon Jun 13 09:08:10 2015
+// Contact: http://ttcn.ericsson.se
+//
+////////////////////////////////////////////////////////////////////////////////
+// Generated from file(s):
+// - MyXMLSchema.xsd
+// /* xml version = "1.0" encoding = "UTF-8" */
+// /* targetnamespace = "http://www.example.org/2001/XMLSchema/e" */
+////////////////////////////////////////////////////////////////////////////////
+// Modification header(s):
+//-----------------------------------------------------------------------------
+// Modified by:
+// Modification date:
+// Description:
+// Modification contact:
+//------------------------------------------------------------------------------
+////////////////////////////////////////////////////////////////////////////////
+
+
+module http_www_example_org_2001_XMLSchema {
+
+
+import from XSD all;
+
+
+type record AttrDecls
+{
+ record of union {
+ XSD.String attribute,
+ XSD.String attributeGroup
+ } choice_list
+}
+with {
+ variant "untagged";
+ variant (choice_list) "untagged";
+ variant (choice_list[-]) "untagged";
+};
+
+
+type record OpenAttrs
+{
+ record of XSD.String attr optional
+}
+with {
+ variant "name as uncapitalized";
+ variant (attr) "anyAttributes except unqualified, 'http://www.example.org/2001/XMLSchema'";
+};
+
+
+type record Annotated
+{
+ record of XSD.String attr optional,
+ XSD.String asd optional
+}
+with {
+ variant "name as uncapitalized";
+ variant (attr) "anyAttributes except unqualified, 'http://www.example.org/2001/XMLSchema'";
+};
+
+
+type union TypeDefParticle
+{
+ XSD.String group_
+}
+with {
+ variant "untagged";
+ variant (group_) "name as 'group'";
+};
+
+
+type record RestrictionType
+{
+ record of XSD.String attr optional,
+ XSD.String asd optional,
+ union {
+ TypeDefParticle typeDefParticle
+ } choice optional,
+ record of union {
+ XSD.String attribute,
+ XSD.String attributeGroup
+ } choice_list
+}
+with {
+ variant "name as uncapitalized";
+ variant (attr) "anyAttributes except unqualified, 'http://www.example.org/2001/XMLSchema'";
+ variant (choice) "untagged";
+ variant (choice_list) "untagged";
+ variant (choice_list[-]) "untagged";
+};
+
+
+type record ComplexRestrictionType
+{
+ record of XSD.String attr optional,
+ union {
+ TypeDefParticle typeDefParticle
+ } choice,
+ record of union {
+ XSD.String attribute,
+ XSD.String attributeGroup
+ } choice_list
+}
+with {
+ variant "name as uncapitalized";
+ variant (attr) "anyAttributes except unqualified, 'http://www.example.org/2001/XMLSchema'";
+ variant (choice) "untagged";
+ variant (choice_list) "untagged";
+ variant (choice_list[-]) "untagged";
+};
+
+
+}
+with {
+ encode "XML";
+ variant "namespace as 'http://www.example.org/2001/XMLSchema' prefix 'a'";
+ variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'";
+ variant "elementFormQualified";
+}
<File path="../xsd/included_without_namespace.xsd" />
<File path="../xsd/list_complextype.xsd" />
<File path="../xsd/enumeration_restriction3.xsd" />
+ <File path="../xsd/MyXMLSchema.xsd" />
</File_Group>
<File_Group name="XmlTest_xsds" >
<File path="../XmlTest_xsds/XmlTest_boolean.xsd" />
<File path="../XmlTest_expectedTtcns/www_example_org_including_module_e.ttcn" />
<File path="../XmlTest_expectedTtcns/www_example_org_list_complextype_e.ttcn" />
<File path="../XmlTest_expectedTtcns/www_example_org_enumeration_restriction3_e.ttcn" />
+ <File path="../XmlTest_expectedTtcns/http_www_example_org_2001_XMLSchema_e.ttcn" />
</File_Group>
<File_Group name="XmlTest_src" >
<File path="xmlTest_Shell.ttcn" />
}
}//tc_
+ testcase tc_xmlschema() runs on xmlTest_CT {
+ f_shellCommandWithVerdict("xsd2ttcn MyXMLSchema.xsd","",c_shell_successWithoutWarningAndError)
+
+ if(getverdict==pass) {
+ f_compareFiles(
+ "http_www_example_org_2001_XMLSchema_e.ttcn",
+ "http_www_example_org_2001_XMLSchema.ttcn", c_numOfDiff_headerModNameAndNamespace);
+ }
+ }//tc_
+
testcase tc_complex_restriction_encDec() runs on xmlTest_CT
{
var MySubjects4Restriction vl_pdu:={
execute(tc_complex_nillable());
execute(tc_nillable_fixed());
execute(tc_no_ns_connector());
+ execute(tc_xmlschema());
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema targetNamespace="http://www.example.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:a="http://www.example.org/2001/XMLSchema">
+
+
+
+<xs:group name="attrDecls">
+ <xs:sequence>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="attribute" type="xs:string"/>
+ <xs:element name="attributeGroup" type="xs:string"/>
+ </xs:choice>
+ </xs:sequence>
+</xs:group>
+
+
+
+<xs:complexType name="openAttrs">
+ <xs:complexContent>
+ <xs:restriction base="xs:anyType">
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:restriction>
+ </xs:complexContent>
+</xs:complexType>
+
+<xs:complexType name="annotated">
+ <xs:complexContent>
+ <xs:extension base="a:openAttrs">
+ <xs:sequence>
+ <xs:element type="xs:string" name="asd" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+</xs:complexType>
+
+
+<xs:group name="typeDefParticle">
+ <xs:choice>
+ <xs:element name="group" type="xs:string"/>
+ </xs:choice>
+</xs:group>
+
+
+<xs:complexType name="restrictionType">
+ <xs:complexContent>
+ <xs:extension base="a:annotated">
+ <xs:sequence>
+ <xs:choice minOccurs="0">
+ <xs:group ref="a:typeDefParticle"/>
+ </xs:choice>
+ <xs:group ref="a:attrDecls"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+</xs:complexType>
+
+
+<xs:complexType name="complexRestrictionType">
+ <xs:complexContent>
+ <xs:restriction base="a:restrictionType">
+ <xs:sequence>
+ <xs:choice minOccurs="1">
+ <xs:group ref="a:typeDefParticle"/>
+ </xs:choice>
+ <xs:group ref="a:attrDecls"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:restriction>
+ </xs:complexContent>
+</xs:complexType>
+
+
+</xs:schema>
}
switch (useVal) {
case optional:
- minOccurs = 0;
- maxOccurs = 1;
+ setMinOccurs(0);
+ setMaxOccurs(1);
break;
case required:
- minOccurs = 1;
- maxOccurs = 1;
+ setMinOccurs(1);
+ setMaxOccurs(1);
break;
case prohibited:
- minOccurs = 0;
- maxOccurs = 0;
+ setMinOccurs(0);
+ setMaxOccurs(0);
setInvisible();
break;
}
- isOptional = isOptional || (minOccurs == 0 && maxOccurs == 1);
+ isOptional = isOptional || (getMinOccurs() == 0 && getMaxOccurs() == 1);
}
void AttributeType::applyNamespaceAttribute(VariantMode varLabel) {
}
void AttributeType::applyMinMaxOccursAttribute(unsigned long long min, unsigned long long max) {
- minOccurs = min;
- maxOccurs = max;
+ setMinOccurs(min);
+ setMaxOccurs(max);
}
void AttributeType::dump(unsigned int depth) const {
name.originalValueWoPrefix.c_str(), name.convertedValue.c_str(), (const void*) this);
fprintf(stderr, "%*s %s Type: \n", depth * 2, "", type.convertedValue.c_str());
fprintf(stderr, "%*s type %s \n", (depth + 1) * 2, "", type.convertedValue.c_str());
- fprintf(stderr, "%*s (%llu .. %llu)\n", (depth + 1) * 2, "", minOccurs, maxOccurs);
+ fprintf(stderr, "%*s (%llu .. %llu)\n", (depth + 1) * 2, "", getMinOccurs(), getMaxOccurs());
fprintf(stderr, "%*s %d variants: ", (depth + 1) * 2, "", (int) variant.size());
for (List<Mstring>::iterator var = variant.begin(); var; var = var->Next) {
fprintf(stderr, "%s, ", var->Data.c_str());
type.convertedValue = other.getType().convertedValue;
type.originalValueWoPrefix = other.getType().convertedValue.getValueWithoutPrefix(':');
- if (other.getMinOccurs() > minOccurs || other.getMaxOccurs() < maxOccurs) {
+ if (other.getMinOccurs() > getMinOccurs() ||
+ other.getMaxOccurs() < getMaxOccurs()) {
if (!on_attributes) {
expstring_t temp = memptystr();
temp = mputprintf(
temp,
"The occurrence range (%llu .. %llu) of the element (%s) is not compatible "
"with the occurrence range (%llu .. %llu) of the referenced element.",
- minOccurs,
- maxOccurs,
+ getMinOccurs(),
+ getMaxOccurs(),
name.originalValueWoPrefix.c_str(),
other.getMinOccurs(),
other.getMaxOccurs());
TTCN3ModuleInventory::getInstance().incrNumErrors();
}
} else {
- minOccurs = llmax(minOccurs, other.getMinOccurs());
- maxOccurs = llmin(maxOccurs, other.getMaxOccurs());
+ setMinOccurs(llmax(getMinOccurs(), other.getMinOccurs()));
+ setMaxOccurs(llmin(getMaxOccurs(), other.getMaxOccurs()));
}
for (List<Mstring>::iterator var = other.getVariantRef().begin(); var; var = var->Next) {
if (path.empty()) {
if (!top) {
Mstring field_prefix = empty_string;
- if(parent->minOccurs == 0 && parent->maxOccurs == ULLONG_MAX){
+ if(parent->getMinOccurs() == 0 && parent->getMaxOccurs() == ULLONG_MAX){
field_prefix = "[-].";
}
path = field_prefix + getName().convertedValue;
SimpleType::finalModification();
//Set isOptional field
- isOptional = isOptional || (minOccurs == 0 && maxOccurs == 1);
+ isOptional = isOptional || (getMinOccurs() == 0 && getMaxOccurs() == 1);
//
List<Mstring> enumNames;
for (List<ComplexType*>::iterator field = complexfields.begin(), nextField; field; field = nextField) {
nextField = field->Next;
//Remove invisible fields
- if ((field->Data->minOccurs == 0 && field->Data->maxOccurs == 0) || !field->Data->isVisible()) {
+ if ((field->Data->getMinOccurs() == 0 && field->Data->getMaxOccurs() == 0) || !field->Data->isVisible()) {
delete field->Data;
field->Data = NULL;
complexfields.remove(field);
if (top) {
bool useUnionVariantWhenMainTypeIsRecordOf = false;
for (List<Mstring>::iterator var = variant.end(); var; var = var->Prev) {
- if ((minOccurs != 1 || maxOccurs != 1) && (var->Data == "\"useUnion\"")) { // main type is a record of
+ if ((getMinOccurs() != 1 || getMaxOccurs() != 1) && (var->Data == "\"useUnion\"")) { // main type is a record of
useUnionVariantWhenMainTypeIsRecordOf = true; // TR HL15893
} else {
container.push_back(Mstring("variant ") + Mstring(var->Data.c_str()) + Mstring(";\n"));
for (List<Mstring>::iterator field = enumfields.begin(); field; field = field->Next) {
fprintf(stderr, "%*s enum: %s\n", depth * 2 + depth, "", field->Data.c_str());
}
- fprintf(stderr, "%*s (%llu .. %llu) | Optional:%s | List:%s\n", (depth + 1) * 2, "", minOccurs, maxOccurs, isOptional ? "true" : "false", name.list_extension ? "true" : "false");
+ fprintf(stderr, "%*s (%llu .. %llu) | Optional:%s | List:%s\n", (depth + 1) * 2, "", getMinOccurs(), getMaxOccurs(), isOptional ? "true" : "false", name.list_extension ? "true" : "false");
fprintf(stderr, "%*s %d variants: ", (depth + 1) * 2, "", (int) variant.size());
for (List<Mstring>::iterator var = variant.begin(); var; var = var->Next) {
fprintf(stderr, "%s, ", var->Data.c_str());
if (min != 1 || max != 1) {
if (xsdtype == n_choice) {
- minOccurs = min;
- maxOccurs = max;
+ setMinOccurs(min);
+ setMaxOccurs(max);
addVariant(V_untagged);
first_child = false;
} else if (xsdtype == n_sequence) {
rec->setXsdtype(n_sequence);
rec->addVariant(V_untagged);
rec->addVariant(V_untagged);
- rec->minOccurs = min;
- rec->maxOccurs = max;
+ rec->setMinOccurs(min);
+ rec->setMaxOccurs(max);
complexfields.push_back(rec);
actfield = rec;
- if ((rec->minOccurs == 0 && rec->maxOccurs > 1) || rec->minOccurs > 0) {
+ if ((rec->getMinOccurs() == 0 && rec->getMaxOccurs() > 1) || rec->getMinOccurs() > 0) {
rec->name.list_extension = true;
}
} else {
- minOccurs = min;
- maxOccurs = max;
- if ((minOccurs == 0 && maxOccurs > 1) || minOccurs > 0) {
+ setMinOccurs(min);
+ setMaxOccurs(max);
+ if ((getMinOccurs() == 0 && getMaxOccurs() > 1) || getMinOccurs() > 0) {
if (generate_list_postfix) {
name.list_extension = true;
}
if (parent != NULL && parent->getXsdtype() == n_choice) {
name.list_extension = true;
if ((parent != NULL && parent->getXsdtype() == n_choice)) {
- if (parent->first_child == false && minOccurs == 0) {
+ if (parent->first_child == false && getMinOccurs() == 0) {
parent->first_child = true;
with_union = true;
first_child = false;
}
}
- if (maxOccurs > 1 && generate_list_postfix) {
+ if (getMaxOccurs() > 1 && generate_list_postfix) {
name.list_extension = true;
}
}
ct->getModule()->getTargetNamespace() != "NoTargetNamespace") {
addNameSpaceas = true;
}
- if (ct->getXsdtype() == n_sequence && minOccurs == 1 && maxOccurs == 1 && (parent->getXsdtype() == n_complexType || parent->getXsdtype() == n_sequence)) {
+ if (ct->getXsdtype() == n_sequence && getMinOccurs() == 1 && getMaxOccurs() == 1 && (parent->getXsdtype() == n_complexType || parent->getXsdtype() == n_sequence)) {
for (List<ComplexType*>::iterator c = ct->complexfields.begin(); c; c = c->Next) {
ComplexType * newField = new ComplexType(*c->Data);
parent->complexfields.push_back(newField);
//If the parent optional, then every field is optional
for (List<ComplexType*>::iterator c = ct->complexfields.begin(); c; c = c->Next) {
ComplexType* f = new ComplexType(*c->Data);
- if (minOccurs == 0 && !f->enumerated) {
+ if (getMinOccurs() == 0 && !f->enumerated) {
f->isOptional = true;
}
((ComplexType*) parent)->complexfields.push_back(f);
field->applyReference(*f->Data);
field->type.upload(ct->getName().convertedValue + Mstring(".") + f->Data->getName().convertedValue);
field->type.no_replace = true;
- field->minOccurs = f->Data->minOccurs;
- field->maxOccurs = f->Data->maxOccurs;
+ field->setMinOccurs(f->Data->getMinOccurs());
+ field->setMaxOccurs(f->Data->getMaxOccurs());
complexfields.push_front(field);
setParent(this, field);
}
List<ComplexType*>::iterator field2 = ct->complexfields.begin();
for (; field2; field2 = field2->Next) {
if (field->Data->getName().convertedValue == field2->Data->getName().convertedValue &&
- field->Data->getType().convertedValue == field2->Data->getType().convertedValue) {
+ field->Data->getType().convertedValue == field2->Data->getType().convertedValue &&
+ field->Data->complexfields.size() <= field2->Data->complexfields.size() &&
+ hasMatchingFields(field->Data->complexfields, field2->Data->complexfields)) {
+ // TODO: better algorithm to find matching fields
field->Data->applyReference(*field2->Data, false);
break;
}
}
}
+bool ComplexType::hasMatchingFields(const List<ComplexType*>& mainList, const List<ComplexType*>& subList) const {
+ List<ComplexType*>::iterator field = mainList.begin();
+ for (; field; field = field->Next){
+ List<ComplexType*>::iterator field2 = subList.begin();
+ bool found = false;
+ for (; field2; field2 = field2->Next) {
+ if(field->Data->getName().convertedValue == field2->Data->getName().convertedValue &&
+ field->Data->getType().convertedValue == field2->Data->getType().convertedValue) {
+ found = true;
+ break;
+ }
+ }
+ if(!found) {
+ return false;
+ }
+ }
+ return true;
+}
+
void ComplexType::resolveUnion(SimpleType *st) {
if (parent != NULL && parent->with_union && xsdtype == n_simpleType && !outside_reference.empty()) {
if (st->getXsdtype() != n_NOTSET) {
void resolveComplexTypeExtension();
void resolveComplexTypeRestriction();
void resolveUnion(SimpleType *st);
+ bool hasMatchingFields(const List<ComplexType*>& a, const List<ComplexType*>& b) const;
void printVariant(FILE * file);
, module(a_module)
, name()
, type()
-, minOccurs(1)
-, maxOccurs(1)
, variant()
, variant_ref()
, comment()
, construct(a_construct)
, origin(from_unknown)
, visible(true)
-, nameDepList() {
+, nameDepList()
+, minOccurs(1)
+, maxOccurs(1)
+, min_mod(false)
+, max_mod(false){
switch (a_construct) {
case c_schema:
case c_annotation:
NameType name;
NameType type;
- unsigned long long int minOccurs;
- unsigned long long int maxOccurs;
List<Mstring> variant;
List<Mstring> variant_ref;
List<Mstring> hidden_variant;
/// List of types that depend on this one.
/// Used to propagate the effect of name conversion to the dependents
List<SimpleType*> nameDepList; // no responsibility for elements
-
+
+private:
+ unsigned long long int minOccurs;
+ unsigned long long int maxOccurs;
+ bool min_mod;
+ bool max_mod;
+
public:
RootType(XMLParser * a_parser, TTCN3Module * a_module, const ConstructType a_construct);
void setVisible() {
visible = true;
}
+
+ void setMinOccurs(const unsigned long long int min) {
+ minOccurs = min;
+ min_mod = true;
+ }
+
+ void setMaxOccurs(const unsigned long long int max) {
+ maxOccurs = max;
+ max_mod = true;
+ }
+
+ const bool getMinMod() const {
+ return min_mod;
+ }
+
+ const bool getMaxMod() const {
+ return max_mod;
+ }
const NameType & getName() const {
return name;
case n_list:
type.upload(atts.itemType);
setReference(atts.itemType);
- minOccurs = 0;
- maxOccurs = ULLONG_MAX;
+ setMinOccurs(0);
+ setMaxOccurs(ULLONG_MAX);
addVariant(V_list);
mode = listMode;
break;
}
case n_length:
if (mode == listMode) {
- minOccurs = strtoull(atts.value.c_str(), NULL, 0);
- maxOccurs = strtoull(atts.value.c_str(), NULL, 0);
+ setMinOccurs(strtoull(atts.value.c_str(), NULL, 0));
+ setMaxOccurs(strtoull(atts.value.c_str(), NULL, 0));
break;
}
length.facet_minLength = strtoull(atts.value.c_str(), NULL, 0);
break;
case n_minLength:
if (mode == listMode) {
- minOccurs = strtoull(atts.value.c_str(), NULL, 0);
+ setMinOccurs(strtoull(atts.value.c_str(), NULL, 0));
break;
}
length.facet_minLength = strtoull(atts.value.c_str(), NULL, 0);
break;
case n_maxLength:
if (mode == listMode) {
- maxOccurs = strtoull(atts.value.c_str(), NULL, 0);
+ setMaxOccurs(strtoull(atts.value.c_str(), NULL, 0));
break;
}
length.facet_maxLength = strtoull(atts.value.c_str(), NULL, 0);
addVariant(V_onlyValueHidden, Mstring("\"text 'true' as '1'\""));
}
- isOptional = isOptional || (minOccurs == 0 && maxOccurs == 0);
+ isOptional = isOptional || (getMinOccurs() == 0 && getMaxOccurs() == 0);
// If the type name is the same as the identifier then we have to prefix it
// with the module identifier.