summaryrefslogtreecommitdiff
path: root/src/xmlpatterns/schema
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commite1b2c9deb5943faae2b29be6a5c006f75bb73f06 (patch)
treefc79e45367c0a8fc71185e9afc33f7503a58653c /src/xmlpatterns/schema
downloadqtxmlpatterns-e1b2c9deb5943faae2b29be6a5c006f75bb73f06.tar.gz
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/xmlpatterns/schema')
-rw-r--r--src/xmlpatterns/schema/.gitignore1
-rw-r--r--src/xmlpatterns/schema/builtinschemas.qrc5
-rw-r--r--src/xmlpatterns/schema/doc/All_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/Alternative_diagram.dot11
-rw-r--r--src/xmlpatterns/schema/doc/Annotation_diagram.dot9
-rw-r--r--src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Any_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Assert_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Choice_diagram.dot22
-rw-r--r--src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot47
-rw-r--r--src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot47
-rw-r--r--src/xmlpatterns/schema/doc/ComplexContent_diagram.dot11
-rw-r--r--src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot9
-rw-r--r--src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Field_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot9
-rw-r--r--src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot52
-rw-r--r--src/xmlpatterns/schema/doc/GlobalElement_diagram.dot32
-rw-r--r--src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/Import_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Include_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/KeyRef_diagram.dot12
-rw-r--r--src/xmlpatterns/schema/doc/Key_diagram.dot12
-rw-r--r--src/xmlpatterns/schema/doc/LengthFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/List_diagram.dot9
-rw-r--r--src/xmlpatterns/schema/doc/LocalAll_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot9
-rw-r--r--src/xmlpatterns/schema/doc/LocalChoice_diagram.dot22
-rw-r--r--src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot52
-rw-r--r--src/xmlpatterns/schema/doc/LocalElement_diagram.dot32
-rw-r--r--src/xmlpatterns/schema/doc/LocalSequence_diagram.dot22
-rw-r--r--src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot17
-rw-r--r--src/xmlpatterns/schema/doc/NamedGroup_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/Notation_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Override_diagram.dot21
-rw-r--r--src/xmlpatterns/schema/doc/PatternFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Redefine_diagram.dot15
-rw-r--r--src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot13
-rw-r--r--src/xmlpatterns/schema/doc/Schema_diagram.dot66
-rw-r--r--src/xmlpatterns/schema/doc/Selector_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Sequence_diagram.dot22
-rw-r--r--src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot23
-rw-r--r--src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot87
-rw-r--r--src/xmlpatterns/schema/doc/SimpleContent_diagram.dot11
-rw-r--r--src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot62
-rw-r--r--src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/Union_diagram.dot10
-rw-r--r--src/xmlpatterns/schema/doc/Unique_diagram.dot12
-rw-r--r--src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot6
-rw-r--r--src/xmlpatterns/schema/doc/legend.dot7
-rw-r--r--src/xmlpatterns/schema/qnamespacesupport.cpp160
-rw-r--r--src/xmlpatterns/schema/qnamespacesupport_p.h173
-rw-r--r--src/xmlpatterns/schema/qxsdalternative.cpp68
-rw-r--r--src/xmlpatterns/schema/qxsdalternative_p.h114
-rw-r--r--src/xmlpatterns/schema/qxsdannotated.cpp63
-rw-r--r--src/xmlpatterns/schema/qxsdannotated_p.h96
-rw-r--r--src/xmlpatterns/schema/qxsdannotation.cpp78
-rw-r--r--src/xmlpatterns/schema/qxsdannotation_p.h127
-rw-r--r--src/xmlpatterns/schema/qxsdapplicationinformation.cpp68
-rw-r--r--src/xmlpatterns/schema/qxsdapplicationinformation_p.h115
-rw-r--r--src/xmlpatterns/schema/qxsdassertion.cpp58
-rw-r--r--src/xmlpatterns/schema/qxsdassertion_p.h101
-rw-r--r--src/xmlpatterns/schema/qxsdattribute.cpp130
-rw-r--r--src/xmlpatterns/schema/qxsdattribute_p.h246
-rw-r--r--src/xmlpatterns/schema/qxsdattributegroup.cpp73
-rw-r--r--src/xmlpatterns/schema/qxsdattributegroup_p.h122
-rw-r--r--src/xmlpatterns/schema/qxsdattributereference.cpp88
-rw-r--r--src/xmlpatterns/schema/qxsdattributereference_p.h147
-rw-r--r--src/xmlpatterns/schema/qxsdattributeterm.cpp58
-rw-r--r--src/xmlpatterns/schema/qxsdattributeterm_p.h96
-rw-r--r--src/xmlpatterns/schema/qxsdattributeuse.cpp136
-rw-r--r--src/xmlpatterns/schema/qxsdattributeuse_p.h224
-rw-r--r--src/xmlpatterns/schema/qxsdcomplextype.cpp231
-rw-r--r--src/xmlpatterns/schema/qxsdcomplextype_p.h404
-rw-r--r--src/xmlpatterns/schema/qxsddocumentation.cpp86
-rw-r--r--src/xmlpatterns/schema/qxsddocumentation_p.h137
-rw-r--r--src/xmlpatterns/schema/qxsdelement.cpp244
-rw-r--r--src/xmlpatterns/schema/qxsdelement_p.h403
-rw-r--r--src/xmlpatterns/schema/qxsdfacet.cpp124
-rw-r--r--src/xmlpatterns/schema/qxsdfacet_p.h213
-rw-r--r--src/xmlpatterns/schema/qxsdidcache.cpp66
-rw-r--r--src/xmlpatterns/schema/qxsdidcache_p.h99
-rw-r--r--src/xmlpatterns/schema/qxsdidchelper.cpp137
-rw-r--r--src/xmlpatterns/schema/qxsdidchelper_p.h186
-rw-r--r--src/xmlpatterns/schema/qxsdidentityconstraint.cpp93
-rw-r--r--src/xmlpatterns/schema/qxsdidentityconstraint_p.h173
-rw-r--r--src/xmlpatterns/schema/qxsdinstancereader.cpp196
-rw-r--r--src/xmlpatterns/schema/qxsdinstancereader_p.h189
-rw-r--r--src/xmlpatterns/schema/qxsdmodelgroup.cpp78
-rw-r--r--src/xmlpatterns/schema/qxsdmodelgroup_p.h139
-rw-r--r--src/xmlpatterns/schema/qxsdnotation.cpp68
-rw-r--r--src/xmlpatterns/schema/qxsdnotation_p.h119
-rw-r--r--src/xmlpatterns/schema/qxsdparticle.cpp95
-rw-r--r--src/xmlpatterns/schema/qxsdparticle_p.h154
-rw-r--r--src/xmlpatterns/schema/qxsdparticlechecker.cpp570
-rw-r--r--src/xmlpatterns/schema/qxsdparticlechecker_p.h106
-rw-r--r--src/xmlpatterns/schema/qxsdreference.cpp83
-rw-r--r--src/xmlpatterns/schema/qxsdreference_p.h145
-rw-r--r--src/xmlpatterns/schema/qxsdschema.cpp272
-rw-r--r--src/xmlpatterns/schema/qxsdschema_p.h301
-rw-r--r--src/xmlpatterns/schema/qxsdschemachecker.cpp2061
-rw-r--r--src/xmlpatterns/schema/qxsdschemachecker_helper.cpp306
-rw-r--r--src/xmlpatterns/schema/qxsdschemachecker_p.h284
-rw-r--r--src/xmlpatterns/schema/qxsdschemachecker_setup.cpp327
-rw-r--r--src/xmlpatterns/schema/qxsdschemacontext.cpp528
-rw-r--r--src/xmlpatterns/schema/qxsdschemacontext_p.h187
-rw-r--r--src/xmlpatterns/schema/qxsdschemadebugger.cpp226
-rw-r--r--src/xmlpatterns/schema/qxsdschemadebugger_p.h127
-rw-r--r--src/xmlpatterns/schema/qxsdschemahelper.cpp821
-rw-r--r--src/xmlpatterns/schema/qxsdschemahelper_p.h217
-rw-r--r--src/xmlpatterns/schema/qxsdschemamerger.cpp157
-rw-r--r--src/xmlpatterns/schema/qxsdschemamerger_p.h99
-rw-r--r--src/xmlpatterns/schema/qxsdschemaparser.cpp6119
-rw-r--r--src/xmlpatterns/schema/qxsdschemaparser_p.h739
-rw-r--r--src/xmlpatterns/schema/qxsdschemaparser_setup.cpp1110
-rw-r--r--src/xmlpatterns/schema/qxsdschemaparsercontext.cpp603
-rw-r--r--src/xmlpatterns/schema/qxsdschemaparsercontext_p.h231
-rw-r--r--src/xmlpatterns/schema/qxsdschemaresolver.cpp1743
-rw-r--r--src/xmlpatterns/schema/qxsdschemaresolver_p.h578
-rw-r--r--src/xmlpatterns/schema/qxsdschematoken.cpp2981
-rw-r--r--src/xmlpatterns/schema/qxsdschematoken_p.h209
-rw-r--r--src/xmlpatterns/schema/qxsdschematypesfactory.cpp126
-rw-r--r--src/xmlpatterns/schema/qxsdschematypesfactory_p.h109
-rw-r--r--src/xmlpatterns/schema/qxsdsimpletype.cpp148
-rw-r--r--src/xmlpatterns/schema/qxsdsimpletype_p.h219
-rw-r--r--src/xmlpatterns/schema/qxsdstatemachine.cpp413
-rw-r--r--src/xmlpatterns/schema/qxsdstatemachine_p.h308
-rw-r--r--src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp260
-rw-r--r--src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h141
-rw-r--r--src/xmlpatterns/schema/qxsdterm.cpp68
-rw-r--r--src/xmlpatterns/schema/qxsdterm_p.h114
-rw-r--r--src/xmlpatterns/schema/qxsdtypechecker.cpp1339
-rw-r--r--src/xmlpatterns/schema/qxsdtypechecker_p.h189
-rw-r--r--src/xmlpatterns/schema/qxsduserschematype.cpp75
-rw-r--r--src/xmlpatterns/schema/qxsduserschematype_p.h124
-rw-r--r--src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp215
-rw-r--r--src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h179
-rw-r--r--src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp1276
-rw-r--r--src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h296
-rw-r--r--src/xmlpatterns/schema/qxsdwildcard.cpp115
-rw-r--r--src/xmlpatterns/schema/qxsdwildcard_p.h199
-rw-r--r--src/xmlpatterns/schema/qxsdxpathexpression.cpp88
-rw-r--r--src/xmlpatterns/schema/qxsdxpathexpression_p.h143
-rw-r--r--src/xmlpatterns/schema/schema.pri93
-rw-r--r--src/xmlpatterns/schema/schemas/xml.xsd145
-rw-r--r--src/xmlpatterns/schema/schemas/xml.xsd-LICENSE40
-rw-r--r--src/xmlpatterns/schema/tokens.xml155
156 files changed, 34864 insertions, 0 deletions
diff --git a/src/xmlpatterns/schema/.gitignore b/src/xmlpatterns/schema/.gitignore
new file mode 100644
index 0000000..2b29f27
--- /dev/null
+++ b/src/xmlpatterns/schema/.gitignore
@@ -0,0 +1 @@
+tests
diff --git a/src/xmlpatterns/schema/builtinschemas.qrc b/src/xmlpatterns/schema/builtinschemas.qrc
new file mode 100644
index 0000000..fb43d78
--- /dev/null
+++ b/src/xmlpatterns/schema/builtinschemas.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file alias="http://www.w3.org/XML/1998/namespace">schemas/xml.xsd</file>
+</qresource>
+</RCC>
diff --git a/src/xmlpatterns/schema/doc/All_diagram.dot b/src/xmlpatterns/schema/doc/All_diagram.dot
new file mode 100644
index 0000000..3352b72
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/All_diagram.dot
@@ -0,0 +1,13 @@
+digraph All {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Alternative_diagram.dot b/src/xmlpatterns/schema/doc/Alternative_diagram.dot
new file mode 100644
index 0000000..2119c49
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Alternative_diagram.dot
@@ -0,0 +1,11 @@
+digraph Alternative {
+ mindist = 2.0
+ 1 -> 3 [label="complexType"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 2 -> 3 [label="complexType"]
+ 2 -> 3 [label="simpleType"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Annotation_diagram.dot b/src/xmlpatterns/schema/doc/Annotation_diagram.dot
new file mode 100644
index 0000000..260b6f7
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Annotation_diagram.dot
@@ -0,0 +1,9 @@
+digraph Annotation {
+ mindist = 2.0
+ 1 -> 2 [label="appinfo"]
+ 1 -> 2 [label="documentation"]
+ 2 -> 2 [label="appinfo"]
+ 2 -> 2 [label="documentation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot b/src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot
new file mode 100644
index 0000000..d252ebd
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot
@@ -0,0 +1,6 @@
+digraph AnyAttribute {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Any_diagram.dot b/src/xmlpatterns/schema/doc/Any_diagram.dot
new file mode 100644
index 0000000..f54063f
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Any_diagram.dot
@@ -0,0 +1,6 @@
+digraph Any {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Assert_diagram.dot b/src/xmlpatterns/schema/doc/Assert_diagram.dot
new file mode 100644
index 0000000..7093bef
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Assert_diagram.dot
@@ -0,0 +1,6 @@
+digraph Assert {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Choice_diagram.dot b/src/xmlpatterns/schema/doc/Choice_diagram.dot
new file mode 100644
index 0000000..7b32016
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Choice_diagram.dot
@@ -0,0 +1,22 @@
+digraph Choice {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="group"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="group"]
+ 2 -> 3 [label="sequence"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="choice"]
+ 3 -> 3 [label="group"]
+ 3 -> 3 [label="sequence"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot b/src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot
new file mode 100644
index 0000000..6131612
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot
@@ -0,0 +1,47 @@
+digraph ComplexContentExtension {
+ mindist = 2.0
+ 1 -> 4 [label="choice"]
+ 1 -> 4 [label="group"]
+ 1 -> 4 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 4 [label="sequence"]
+ 1 -> 6 [label="anyAttribute"]
+ 1 -> 7 [label="assert"]
+ 1 -> 3 [label="openContent"]
+ 1 -> 5 [label="attribute"]
+ 1 -> 5 [label="attributeGroup"]
+ 2 -> 4 [label="choice"]
+ 2 -> 4 [label="group"]
+ 2 -> 4 [label="all"]
+ 2 -> 4 [label="sequence"]
+ 2 -> 6 [label="anyAttribute"]
+ 2 -> 7 [label="assert"]
+ 2 -> 3 [label="openContent"]
+ 2 -> 5 [label="attribute"]
+ 2 -> 5 [label="attributeGroup"]
+ 3 -> 4 [label="choice"]
+ 3 -> 4 [label="group"]
+ 3 -> 4 [label="all"]
+ 3 -> 4 [label="sequence"]
+ 3 -> 6 [label="anyAttribute"]
+ 3 -> 7 [label="assert"]
+ 3 -> 5 [label="attribute"]
+ 3 -> 5 [label="attributeGroup"]
+ 4 -> 6 [label="anyAttribute"]
+ 4 -> 7 [label="assert"]
+ 4 -> 5 [label="attribute"]
+ 4 -> 5 [label="attributeGroup"]
+ 5 -> 6 [label="anyAttribute"]
+ 5 -> 7 [label="assert"]
+ 5 -> 5 [label="attribute"]
+ 5 -> 5 [label="attributeGroup"]
+ 6 -> 7 [label="assert"]
+ 7 -> 7 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+ 7 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot b/src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot
new file mode 100644
index 0000000..bfda892
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot
@@ -0,0 +1,47 @@
+digraph ComplexContentRestriction {
+ mindist = 2.0
+ 1 -> 4 [label="choice"]
+ 1 -> 4 [label="group"]
+ 1 -> 4 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 4 [label="sequence"]
+ 1 -> 6 [label="anyAttribute"]
+ 1 -> 7 [label="assert"]
+ 1 -> 3 [label="openContent"]
+ 1 -> 5 [label="attribute"]
+ 1 -> 5 [label="attributeGroup"]
+ 2 -> 4 [label="choice"]
+ 2 -> 4 [label="group"]
+ 2 -> 4 [label="all"]
+ 2 -> 4 [label="sequence"]
+ 2 -> 6 [label="anyAttribute"]
+ 2 -> 7 [label="assert"]
+ 2 -> 3 [label="openContent"]
+ 2 -> 5 [label="attribute"]
+ 2 -> 5 [label="attributeGroup"]
+ 3 -> 4 [label="choice"]
+ 3 -> 4 [label="group"]
+ 3 -> 4 [label="all"]
+ 3 -> 4 [label="sequence"]
+ 3 -> 6 [label="anyAttribute"]
+ 3 -> 7 [label="assert"]
+ 3 -> 5 [label="attribute"]
+ 3 -> 5 [label="attributeGroup"]
+ 4 -> 6 [label="anyAttribute"]
+ 4 -> 7 [label="assert"]
+ 4 -> 5 [label="attribute"]
+ 4 -> 5 [label="attributeGroup"]
+ 5 -> 6 [label="anyAttribute"]
+ 5 -> 7 [label="assert"]
+ 5 -> 5 [label="attribute"]
+ 5 -> 5 [label="attributeGroup"]
+ 6 -> 7 [label="assert"]
+ 7 -> 7 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+ 7 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/ComplexContent_diagram.dot b/src/xmlpatterns/schema/doc/ComplexContent_diagram.dot
new file mode 100644
index 0000000..949c27e
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/ComplexContent_diagram.dot
@@ -0,0 +1,11 @@
+digraph ComplexContent {
+ mindist = 2.0
+ 1 -> 3 [label="restriction"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="extension"]
+ 2 -> 3 [label="restriction"]
+ 2 -> 3 [label="extension"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot b/src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot
new file mode 100644
index 0000000..61e7d14
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot
@@ -0,0 +1,9 @@
+digraph DefaultOpenContent {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="any"]
+ 2 -> 3 [label="any"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot b/src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot
new file mode 100644
index 0000000..91be76b
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph EnumerationFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Field_diagram.dot b/src/xmlpatterns/schema/doc/Field_diagram.dot
new file mode 100644
index 0000000..1c597b3
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Field_diagram.dot
@@ -0,0 +1,6 @@
+digraph Field {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot b/src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot
new file mode 100644
index 0000000..5e098b3
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph FractionDigitsFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot b/src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot
new file mode 100644
index 0000000..25a1a43
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot
@@ -0,0 +1,9 @@
+digraph GlobalAttribute {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 2 -> 3 [label="simpleType"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot b/src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot
new file mode 100644
index 0000000..05e40b7
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot
@@ -0,0 +1,52 @@
+digraph GlobalComplexType {
+ mindist = 2.0
+ 1 -> 5 [label="choice"]
+ 1 -> 3 [label="complexContent"]
+ 1 -> 5 [label="group"]
+ 1 -> 5 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 5 [label="sequence"]
+ 1 -> 3 [label="simpleContent"]
+ 1 -> 7 [label="anyAttribute"]
+ 1 -> 8 [label="assert"]
+ 1 -> 4 [label="openContent"]
+ 1 -> 6 [label="attribute"]
+ 1 -> 6 [label="attributeGroup"]
+ 2 -> 5 [label="choice"]
+ 2 -> 3 [label="complexContent"]
+ 2 -> 5 [label="group"]
+ 2 -> 5 [label="all"]
+ 2 -> 5 [label="sequence"]
+ 2 -> 3 [label="simpleContent"]
+ 2 -> 7 [label="anyAttribute"]
+ 2 -> 8 [label="assert"]
+ 2 -> 4 [label="openContent"]
+ 2 -> 6 [label="attribute"]
+ 2 -> 6 [label="attributeGroup"]
+ 4 -> 5 [label="choice"]
+ 4 -> 5 [label="group"]
+ 4 -> 5 [label="all"]
+ 4 -> 5 [label="sequence"]
+ 4 -> 7 [label="anyAttribute"]
+ 4 -> 8 [label="assert"]
+ 4 -> 6 [label="attribute"]
+ 4 -> 6 [label="attributeGroup"]
+ 5 -> 7 [label="anyAttribute"]
+ 5 -> 8 [label="assert"]
+ 5 -> 6 [label="attribute"]
+ 5 -> 6 [label="attributeGroup"]
+ 6 -> 7 [label="anyAttribute"]
+ 6 -> 8 [label="assert"]
+ 6 -> 6 [label="attribute"]
+ 6 -> 6 [label="attributeGroup"]
+ 7 -> 8 [label="assert"]
+ 8 -> 8 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+ 7 [shape=doublecircle, style=filled, color=green]
+ 8 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/GlobalElement_diagram.dot b/src/xmlpatterns/schema/doc/GlobalElement_diagram.dot
new file mode 100644
index 0000000..20447a7
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/GlobalElement_diagram.dot
@@ -0,0 +1,32 @@
+digraph GlobalElement {
+ mindist = 2.0
+ 1 -> 3 [label="complexType"]
+ 1 -> 4 [label="alternative"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 5 [label="key"]
+ 1 -> 3 [label="simpleType"]
+ 1 -> 5 [label="keyref"]
+ 1 -> 5 [label="unique"]
+ 2 -> 3 [label="complexType"]
+ 2 -> 4 [label="alternative"]
+ 2 -> 5 [label="key"]
+ 2 -> 3 [label="simpleType"]
+ 2 -> 5 [label="keyref"]
+ 2 -> 5 [label="unique"]
+ 3 -> 4 [label="alternative"]
+ 3 -> 5 [label="key"]
+ 3 -> 5 [label="keyref"]
+ 3 -> 5 [label="unique"]
+ 4 -> 4 [label="alternative"]
+ 4 -> 5 [label="key"]
+ 4 -> 5 [label="keyref"]
+ 4 -> 5 [label="unique"]
+ 5 -> 5 [label="key"]
+ 5 -> 5 [label="keyref"]
+ 5 -> 5 [label="unique"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot b/src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot
new file mode 100644
index 0000000..ccb7f54
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot
@@ -0,0 +1,13 @@
+digraph GlobalSimpleType {
+ mindist = 2.0
+ 1 -> 3 [label="restriction"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="list"]
+ 1 -> 3 [label="union"]
+ 2 -> 3 [label="restriction"]
+ 2 -> 3 [label="list"]
+ 2 -> 3 [label="union"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Import_diagram.dot b/src/xmlpatterns/schema/doc/Import_diagram.dot
new file mode 100644
index 0000000..3484bc3
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Import_diagram.dot
@@ -0,0 +1,6 @@
+digraph Import {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Include_diagram.dot b/src/xmlpatterns/schema/doc/Include_diagram.dot
new file mode 100644
index 0000000..357e4c9
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Include_diagram.dot
@@ -0,0 +1,6 @@
+digraph Include {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/KeyRef_diagram.dot b/src/xmlpatterns/schema/doc/KeyRef_diagram.dot
new file mode 100644
index 0000000..ff425b9
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/KeyRef_diagram.dot
@@ -0,0 +1,12 @@
+digraph KeyRef {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="selector"]
+ 2 -> 3 [label="selector"]
+ 3 -> 4 [label="field"]
+ 4 -> 4 [label="field"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=circle, style=filled, color=red]
+ 4 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Key_diagram.dot b/src/xmlpatterns/schema/doc/Key_diagram.dot
new file mode 100644
index 0000000..bbc09cd
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Key_diagram.dot
@@ -0,0 +1,12 @@
+digraph Key {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="selector"]
+ 2 -> 3 [label="selector"]
+ 3 -> 4 [label="field"]
+ 4 -> 4 [label="field"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=circle, style=filled, color=red]
+ 4 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LengthFacet_diagram.dot b/src/xmlpatterns/schema/doc/LengthFacet_diagram.dot
new file mode 100644
index 0000000..1f9205b
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LengthFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph LengthFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/List_diagram.dot b/src/xmlpatterns/schema/doc/List_diagram.dot
new file mode 100644
index 0000000..44cc698
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/List_diagram.dot
@@ -0,0 +1,9 @@
+digraph List {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 2 -> 3 [label="simpleType"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalAll_diagram.dot b/src/xmlpatterns/schema/doc/LocalAll_diagram.dot
new file mode 100644
index 0000000..88f1b61
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalAll_diagram.dot
@@ -0,0 +1,13 @@
+digraph LocalAll {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot b/src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot
new file mode 100644
index 0000000..b01f0cf
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot
@@ -0,0 +1,9 @@
+digraph LocalAttribute {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 2 -> 3 [label="simpleType"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalChoice_diagram.dot b/src/xmlpatterns/schema/doc/LocalChoice_diagram.dot
new file mode 100644
index 0000000..b16c47f
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalChoice_diagram.dot
@@ -0,0 +1,22 @@
+digraph LocalChoice {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="group"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="group"]
+ 2 -> 3 [label="sequence"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="choice"]
+ 3 -> 3 [label="group"]
+ 3 -> 3 [label="sequence"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot b/src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot
new file mode 100644
index 0000000..92c54b7
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot
@@ -0,0 +1,52 @@
+digraph LocalComplexType {
+ mindist = 2.0
+ 1 -> 5 [label="choice"]
+ 1 -> 3 [label="complexContent"]
+ 1 -> 5 [label="group"]
+ 1 -> 5 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 5 [label="sequence"]
+ 1 -> 3 [label="simpleContent"]
+ 1 -> 7 [label="anyAttribute"]
+ 1 -> 8 [label="assert"]
+ 1 -> 4 [label="openContent"]
+ 1 -> 6 [label="attribute"]
+ 1 -> 6 [label="attributeGroup"]
+ 2 -> 5 [label="choice"]
+ 2 -> 3 [label="complexContent"]
+ 2 -> 5 [label="group"]
+ 2 -> 5 [label="all"]
+ 2 -> 5 [label="sequence"]
+ 2 -> 3 [label="simpleContent"]
+ 2 -> 7 [label="anyAttribute"]
+ 2 -> 8 [label="assert"]
+ 2 -> 4 [label="openContent"]
+ 2 -> 6 [label="attribute"]
+ 2 -> 6 [label="attributeGroup"]
+ 4 -> 5 [label="choice"]
+ 4 -> 5 [label="group"]
+ 4 -> 5 [label="all"]
+ 4 -> 5 [label="sequence"]
+ 4 -> 7 [label="anyAttribute"]
+ 4 -> 8 [label="assert"]
+ 4 -> 6 [label="attribute"]
+ 4 -> 6 [label="attributeGroup"]
+ 5 -> 7 [label="anyAttribute"]
+ 5 -> 8 [label="assert"]
+ 5 -> 6 [label="attribute"]
+ 5 -> 6 [label="attributeGroup"]
+ 6 -> 7 [label="anyAttribute"]
+ 6 -> 8 [label="assert"]
+ 6 -> 6 [label="attribute"]
+ 6 -> 6 [label="attributeGroup"]
+ 7 -> 8 [label="assert"]
+ 8 -> 8 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+ 7 [shape=doublecircle, style=filled, color=green]
+ 8 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalElement_diagram.dot b/src/xmlpatterns/schema/doc/LocalElement_diagram.dot
new file mode 100644
index 0000000..397397a
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalElement_diagram.dot
@@ -0,0 +1,32 @@
+digraph LocalElement {
+ mindist = 2.0
+ 1 -> 3 [label="complexType"]
+ 1 -> 4 [label="alternative"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 5 [label="key"]
+ 1 -> 3 [label="simpleType"]
+ 1 -> 5 [label="keyref"]
+ 1 -> 5 [label="unique"]
+ 2 -> 3 [label="complexType"]
+ 2 -> 4 [label="alternative"]
+ 2 -> 5 [label="key"]
+ 2 -> 3 [label="simpleType"]
+ 2 -> 5 [label="keyref"]
+ 2 -> 5 [label="unique"]
+ 3 -> 4 [label="alternative"]
+ 3 -> 5 [label="key"]
+ 3 -> 5 [label="keyref"]
+ 3 -> 5 [label="unique"]
+ 4 -> 4 [label="alternative"]
+ 4 -> 5 [label="key"]
+ 4 -> 5 [label="keyref"]
+ 4 -> 5 [label="unique"]
+ 5 -> 5 [label="key"]
+ 5 -> 5 [label="keyref"]
+ 5 -> 5 [label="unique"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalSequence_diagram.dot b/src/xmlpatterns/schema/doc/LocalSequence_diagram.dot
new file mode 100644
index 0000000..0dc7f39
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalSequence_diagram.dot
@@ -0,0 +1,22 @@
+digraph LocalSequence {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="group"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="group"]
+ 2 -> 3 [label="sequence"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="choice"]
+ 3 -> 3 [label="group"]
+ 3 -> 3 [label="sequence"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot b/src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot
new file mode 100644
index 0000000..ac13305
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot
@@ -0,0 +1,13 @@
+digraph LocalSimpleType {
+ mindist = 2.0
+ 1 -> 3 [label="restriction"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="list"]
+ 1 -> 3 [label="union"]
+ 2 -> 3 [label="restriction"]
+ 2 -> 3 [label="list"]
+ 2 -> 3 [label="union"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot
new file mode 100644
index 0000000..28364f7
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MaxExclusiveFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot
new file mode 100644
index 0000000..9e2c265
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MaxInclusiveFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot b/src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot
new file mode 100644
index 0000000..d565217
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MaxLengthFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot
new file mode 100644
index 0000000..d3b3f1f
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MinExclusiveFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot
new file mode 100644
index 0000000..e5ca65d
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MinInclusiveFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot b/src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot
new file mode 100644
index 0000000..1dcced4
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph MinLengthFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot b/src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot
new file mode 100644
index 0000000..1754f67
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot
@@ -0,0 +1,17 @@
+digraph NamedAttributeGroup {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 4 [label="anyAttribute"]
+ 1 -> 3 [label="attribute"]
+ 1 -> 3 [label="attributeGroup"]
+ 2 -> 4 [label="anyAttribute"]
+ 2 -> 3 [label="attribute"]
+ 2 -> 3 [label="attributeGroup"]
+ 3 -> 4 [label="anyAttribute"]
+ 3 -> 3 [label="attribute"]
+ 3 -> 3 [label="attributeGroup"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/NamedGroup_diagram.dot b/src/xmlpatterns/schema/doc/NamedGroup_diagram.dot
new file mode 100644
index 0000000..6d9a289
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/NamedGroup_diagram.dot
@@ -0,0 +1,13 @@
+digraph NamedGroup {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="all"]
+ 2 -> 3 [label="sequence"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Notation_diagram.dot b/src/xmlpatterns/schema/doc/Notation_diagram.dot
new file mode 100644
index 0000000..951f26a
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Notation_diagram.dot
@@ -0,0 +1,6 @@
+digraph Notation {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Override_diagram.dot b/src/xmlpatterns/schema/doc/Override_diagram.dot
new file mode 100644
index 0000000..448451a
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Override_diagram.dot
@@ -0,0 +1,21 @@
+digraph Override {
+ mindist = 2.0
+ 1 -> 2 [label="group"]
+ 1 -> 2 [label="complexType"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 2 [label="simpleType"]
+ 1 -> 2 [label="element"]
+ 1 -> 2 [label="notation"]
+ 1 -> 2 [label="attribute"]
+ 1 -> 2 [label="attributeGroup"]
+ 2 -> 2 [label="group"]
+ 2 -> 2 [label="complexType"]
+ 2 -> 2 [label="annotation"]
+ 2 -> 2 [label="simpleType"]
+ 2 -> 2 [label="element"]
+ 2 -> 2 [label="notation"]
+ 2 -> 2 [label="attribute"]
+ 2 -> 2 [label="attributeGroup"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/PatternFacet_diagram.dot b/src/xmlpatterns/schema/doc/PatternFacet_diagram.dot
new file mode 100644
index 0000000..794d74c
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/PatternFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph PatternFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Redefine_diagram.dot b/src/xmlpatterns/schema/doc/Redefine_diagram.dot
new file mode 100644
index 0000000..ba4871d
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Redefine_diagram.dot
@@ -0,0 +1,15 @@
+digraph Redefine {
+ mindist = 2.0
+ 1 -> 2 [label="group"]
+ 1 -> 2 [label="complexType"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 2 [label="simpleType"]
+ 1 -> 2 [label="attributeGroup"]
+ 2 -> 2 [label="group"]
+ 2 -> 2 [label="complexType"]
+ 2 -> 2 [label="annotation"]
+ 2 -> 2 [label="simpleType"]
+ 2 -> 2 [label="attributeGroup"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot b/src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot
new file mode 100644
index 0000000..fd08872
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot
@@ -0,0 +1,6 @@
+digraph ReferredAttributeGroup {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot b/src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot
new file mode 100644
index 0000000..c32f69f
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot
@@ -0,0 +1,13 @@
+digraph ReferredGroup {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="all"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="all"]
+ 2 -> 3 [label="sequence"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Schema_diagram.dot b/src/xmlpatterns/schema/doc/Schema_diagram.dot
new file mode 100644
index 0000000..7d39337
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Schema_diagram.dot
@@ -0,0 +1,66 @@
+digraph Schema {
+ mindist = 2.0
+ 1 -> 5 [label="group"]
+ 1 -> 5 [label="complexType"]
+ 1 -> 2 [label="import"]
+ 1 -> 2 [label="include"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="defaultOpenContent"]
+ 1 -> 5 [label="simpleType"]
+ 1 -> 5 [label="element"]
+ 1 -> 5 [label="notation"]
+ 1 -> 2 [label="override"]
+ 1 -> 5 [label="attribute"]
+ 1 -> 5 [label="attributeGroup"]
+ 1 -> 2 [label="redefine"]
+ 2 -> 5 [label="group"]
+ 2 -> 5 [label="complexType"]
+ 2 -> 2 [label="import"]
+ 2 -> 2 [label="include"]
+ 2 -> 2 [label="annotation"]
+ 2 -> 3 [label="defaultOpenContent"]
+ 2 -> 5 [label="simpleType"]
+ 2 -> 5 [label="element"]
+ 2 -> 5 [label="notation"]
+ 2 -> 2 [label="override"]
+ 2 -> 5 [label="attribute"]
+ 2 -> 5 [label="attributeGroup"]
+ 2 -> 2 [label="redefine"]
+ 3 -> 5 [label="group"]
+ 3 -> 5 [label="complexType"]
+ 3 -> 4 [label="annotation"]
+ 3 -> 5 [label="simpleType"]
+ 3 -> 5 [label="element"]
+ 3 -> 5 [label="notation"]
+ 3 -> 5 [label="attribute"]
+ 3 -> 5 [label="attributeGroup"]
+ 4 -> 5 [label="group"]
+ 4 -> 5 [label="complexType"]
+ 4 -> 5 [label="simpleType"]
+ 4 -> 5 [label="element"]
+ 4 -> 5 [label="notation"]
+ 4 -> 5 [label="attribute"]
+ 4 -> 5 [label="attributeGroup"]
+ 5 -> 5 [label="group"]
+ 5 -> 5 [label="complexType"]
+ 5 -> 6 [label="annotation"]
+ 5 -> 5 [label="simpleType"]
+ 5 -> 5 [label="element"]
+ 5 -> 5 [label="notation"]
+ 5 -> 5 [label="attribute"]
+ 5 -> 5 [label="attributeGroup"]
+ 6 -> 5 [label="group"]
+ 6 -> 5 [label="complexType"]
+ 6 -> 6 [label="annotation"]
+ 6 -> 5 [label="simpleType"]
+ 6 -> 5 [label="element"]
+ 6 -> 5 [label="notation"]
+ 6 -> 5 [label="attribute"]
+ 6 -> 5 [label="attributeGroup"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Selector_diagram.dot b/src/xmlpatterns/schema/doc/Selector_diagram.dot
new file mode 100644
index 0000000..f3e93dc
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Selector_diagram.dot
@@ -0,0 +1,6 @@
+digraph Selector {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Sequence_diagram.dot b/src/xmlpatterns/schema/doc/Sequence_diagram.dot
new file mode 100644
index 0000000..9172744
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Sequence_diagram.dot
@@ -0,0 +1,22 @@
+digraph Sequence {
+ mindist = 2.0
+ 1 -> 3 [label="choice"]
+ 1 -> 3 [label="group"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="sequence"]
+ 1 -> 3 [label="any"]
+ 1 -> 3 [label="element"]
+ 2 -> 3 [label="choice"]
+ 2 -> 3 [label="group"]
+ 2 -> 3 [label="sequence"]
+ 2 -> 3 [label="any"]
+ 2 -> 3 [label="element"]
+ 3 -> 3 [label="choice"]
+ 3 -> 3 [label="group"]
+ 3 -> 3 [label="sequence"]
+ 3 -> 3 [label="any"]
+ 3 -> 3 [label="element"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot b/src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot
new file mode 100644
index 0000000..3ceebfd
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot
@@ -0,0 +1,23 @@
+digraph SimpleContentExtension {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 4 [label="anyAttribute"]
+ 1 -> 5 [label="assert"]
+ 1 -> 3 [label="attribute"]
+ 1 -> 3 [label="attributeGroup"]
+ 2 -> 4 [label="anyAttribute"]
+ 2 -> 5 [label="assert"]
+ 2 -> 3 [label="attribute"]
+ 2 -> 3 [label="attributeGroup"]
+ 3 -> 4 [label="anyAttribute"]
+ 3 -> 5 [label="assert"]
+ 3 -> 3 [label="attribute"]
+ 3 -> 3 [label="attributeGroup"]
+ 4 -> 5 [label="assert"]
+ 5 -> 5 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot b/src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot
new file mode 100644
index 0000000..75b0b71
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot
@@ -0,0 +1,87 @@
+digraph SimpleContentRestriction {
+ mindist = 2.0
+ 1 -> 3 [label="simpleType"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 4 [label="length"]
+ 1 -> 6 [label="anyAttribute"]
+ 1 -> 4 [label="maxExclusive"]
+ 1 -> 4 [label="totalDigits"]
+ 1 -> 4 [label="maxInclusive"]
+ 1 -> 4 [label="maxLength"]
+ 1 -> 7 [label="assert"]
+ 1 -> 4 [label="assertion"]
+ 1 -> 5 [label="attribute"]
+ 1 -> 4 [label="minExclusive"]
+ 1 -> 5 [label="attributeGroup"]
+ 1 -> 4 [label="minInclusive"]
+ 1 -> 4 [label="minLength"]
+ 1 -> 4 [label="whiteSpace"]
+ 1 -> 4 [label="pattern"]
+ 1 -> 4 [label="enumeration"]
+ 1 -> 4 [label="fractionDigits"]
+ 2 -> 3 [label="simpleType"]
+ 2 -> 4 [label="length"]
+ 2 -> 6 [label="anyAttribute"]
+ 2 -> 4 [label="maxExclusive"]
+ 2 -> 4 [label="totalDigits"]
+ 2 -> 4 [label="maxInclusive"]
+ 2 -> 4 [label="maxLength"]
+ 2 -> 7 [label="assert"]
+ 2 -> 4 [label="assertion"]
+ 2 -> 5 [label="attribute"]
+ 2 -> 4 [label="minExclusive"]
+ 2 -> 5 [label="attributeGroup"]
+ 2 -> 4 [label="minInclusive"]
+ 2 -> 4 [label="minLength"]
+ 2 -> 4 [label="whiteSpace"]
+ 2 -> 4 [label="pattern"]
+ 2 -> 4 [label="enumeration"]
+ 2 -> 4 [label="fractionDigits"]
+ 3 -> 4 [label="fractionDigits"]
+ 3 -> 4 [label="minLength"]
+ 3 -> 4 [label="whiteSpace"]
+ 3 -> 6 [label="anyAttribute"]
+ 3 -> 4 [label="length"]
+ 3 -> 7 [label="assert"]
+ 3 -> 4 [label="maxExclusive"]
+ 3 -> 4 [label="enumeration"]
+ 3 -> 4 [label="assertion"]
+ 3 -> 4 [label="maxInclusive"]
+ 3 -> 5 [label="attribute"]
+ 3 -> 4 [label="maxLength"]
+ 3 -> 4 [label="pattern"]
+ 3 -> 4 [label="totalDigits"]
+ 3 -> 5 [label="attributeGroup"]
+ 3 -> 4 [label="minExclusive"]
+ 3 -> 4 [label="minInclusive"]
+ 4 -> 4 [label="fractionDigits"]
+ 4 -> 4 [label="minLength"]
+ 4 -> 4 [label="whiteSpace"]
+ 4 -> 6 [label="anyAttribute"]
+ 4 -> 4 [label="length"]
+ 4 -> 7 [label="assert"]
+ 4 -> 4 [label="maxExclusive"]
+ 4 -> 4 [label="enumeration"]
+ 4 -> 4 [label="assertion"]
+ 4 -> 4 [label="maxInclusive"]
+ 4 -> 5 [label="attribute"]
+ 4 -> 4 [label="maxLength"]
+ 4 -> 4 [label="pattern"]
+ 4 -> 4 [label="totalDigits"]
+ 4 -> 5 [label="attributeGroup"]
+ 4 -> 4 [label="minExclusive"]
+ 4 -> 4 [label="minInclusive"]
+ 5 -> 6 [label="anyAttribute"]
+ 5 -> 7 [label="assert"]
+ 5 -> 5 [label="attribute"]
+ 5 -> 5 [label="attributeGroup"]
+ 6 -> 7 [label="assert"]
+ 7 -> 7 [label="assert"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+ 5 [shape=doublecircle, style=filled, color=green]
+ 6 [shape=doublecircle, style=filled, color=green]
+ 7 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/SimpleContent_diagram.dot b/src/xmlpatterns/schema/doc/SimpleContent_diagram.dot
new file mode 100644
index 0000000..c996329
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/SimpleContent_diagram.dot
@@ -0,0 +1,11 @@
+digraph SimpleContent {
+ mindist = 2.0
+ 1 -> 3 [label="restriction"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="extension"]
+ 2 -> 3 [label="restriction"]
+ 2 -> 3 [label="extension"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot b/src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot
new file mode 100644
index 0000000..09cb041
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot
@@ -0,0 +1,62 @@
+digraph SimpleRestriction {
+ mindist = 2.0
+ 1 -> 4 [label="fractionDigits"]
+ 1 -> 4 [label="minLength"]
+ 1 -> 4 [label="whiteSpace"]
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 1 -> 4 [label="length"]
+ 1 -> 4 [label="maxExclusive"]
+ 1 -> 4 [label="enumeration"]
+ 1 -> 4 [label="assertion"]
+ 1 -> 4 [label="maxInclusive"]
+ 1 -> 4 [label="maxLength"]
+ 1 -> 4 [label="pattern"]
+ 1 -> 4 [label="totalDigits"]
+ 1 -> 4 [label="minExclusive"]
+ 1 -> 4 [label="minInclusive"]
+ 2 -> 4 [label="fractionDigits"]
+ 2 -> 4 [label="minLength"]
+ 2 -> 4 [label="whiteSpace"]
+ 2 -> 3 [label="simpleType"]
+ 2 -> 4 [label="length"]
+ 2 -> 4 [label="maxExclusive"]
+ 2 -> 4 [label="enumeration"]
+ 2 -> 4 [label="assertion"]
+ 2 -> 4 [label="maxInclusive"]
+ 2 -> 4 [label="maxLength"]
+ 2 -> 4 [label="pattern"]
+ 2 -> 4 [label="totalDigits"]
+ 2 -> 4 [label="minExclusive"]
+ 2 -> 4 [label="minInclusive"]
+ 3 -> 4 [label="fractionDigits"]
+ 3 -> 4 [label="minLength"]
+ 3 -> 4 [label="whiteSpace"]
+ 3 -> 4 [label="length"]
+ 3 -> 4 [label="maxExclusive"]
+ 3 -> 4 [label="enumeration"]
+ 3 -> 4 [label="assertion"]
+ 3 -> 4 [label="maxInclusive"]
+ 3 -> 4 [label="maxLength"]
+ 3 -> 4 [label="pattern"]
+ 3 -> 4 [label="totalDigits"]
+ 3 -> 4 [label="minExclusive"]
+ 3 -> 4 [label="minInclusive"]
+ 4 -> 4 [label="fractionDigits"]
+ 4 -> 4 [label="minLength"]
+ 4 -> 4 [label="whiteSpace"]
+ 4 -> 4 [label="length"]
+ 4 -> 4 [label="maxExclusive"]
+ 4 -> 4 [label="enumeration"]
+ 4 -> 4 [label="assertion"]
+ 4 -> 4 [label="maxInclusive"]
+ 4 -> 4 [label="maxLength"]
+ 4 -> 4 [label="pattern"]
+ 4 -> 4 [label="totalDigits"]
+ 4 -> 4 [label="minExclusive"]
+ 4 -> 4 [label="minInclusive"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+ 4 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot b/src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot
new file mode 100644
index 0000000..0ef4cd6
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph TotalDigitsFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Union_diagram.dot b/src/xmlpatterns/schema/doc/Union_diagram.dot
new file mode 100644
index 0000000..d6c1865
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Union_diagram.dot
@@ -0,0 +1,10 @@
+digraph Union {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="simpleType"]
+ 2 -> 3 [label="simpleType"]
+ 3 -> 3 [label="simpleType"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+ 3 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/Unique_diagram.dot b/src/xmlpatterns/schema/doc/Unique_diagram.dot
new file mode 100644
index 0000000..5b1d098
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/Unique_diagram.dot
@@ -0,0 +1,12 @@
+digraph Unique {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 -> 3 [label="selector"]
+ 2 -> 3 [label="selector"]
+ 3 -> 4 [label="field"]
+ 4 -> 4 [label="field"]
+ 1 [shape=circle, style=filled, color=blue]
+ 2 [shape=circle, style=filled, color=red]
+ 3 [shape=circle, style=filled, color=red]
+ 4 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot b/src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot
new file mode 100644
index 0000000..596403c
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot
@@ -0,0 +1,6 @@
+digraph WhiteSpaceFacet {
+ mindist = 2.0
+ 1 -> 2 [label="annotation"]
+ 1 [shape=doublecircle, style=filled, color=blue]
+ 2 [shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/doc/legend.dot b/src/xmlpatterns/schema/doc/legend.dot
new file mode 100644
index 0000000..4f5792e
--- /dev/null
+++ b/src/xmlpatterns/schema/doc/legend.dot
@@ -0,0 +1,7 @@
+digraph {
+ size="5,4"
+ 1 [label=" start state ", shape=circle, style=filled, color=blue]
+ 2 [label="start/end state", shape=doublecircle, style=filled, color=blue]
+ 3 [label=" internal state", shape=circle, style=filled, color=red]
+ 4 [label=" end state ", shape=doublecircle, style=filled, color=green]
+}
diff --git a/src/xmlpatterns/schema/qnamespacesupport.cpp b/src/xmlpatterns/schema/qnamespacesupport.cpp
new file mode 100644
index 0000000..05b87e3
--- /dev/null
+++ b/src/xmlpatterns/schema/qnamespacesupport.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#include "qnamespacesupport_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NamespaceSupport::NamespaceSupport()
+{
+}
+
+NamespaceSupport::NamespaceSupport(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+{
+ // the XML namespace
+ m_ns.insert(StandardPrefixes::xml, StandardNamespaces::xml);
+}
+
+void NamespaceSupport::setPrefix(const QXmlName::PrefixCode prefixCode, const QXmlName::NamespaceCode namespaceCode)
+{
+ m_ns.insert(prefixCode, namespaceCode);
+}
+
+void NamespaceSupport::setPrefixes(const QXmlStreamNamespaceDeclarations &declarations)
+{
+ for (int i = 0; i < declarations.count(); i++) {
+ const QXmlStreamNamespaceDeclaration declaration = declarations.at(i);
+
+ const QXmlName::PrefixCode prefixCode = m_namePool->allocatePrefix(declaration.prefix().toString());
+ const QXmlName::NamespaceCode namespaceCode = m_namePool->allocateNamespace(declaration.namespaceUri().toString());
+ m_ns.insert(prefixCode, namespaceCode);
+ }
+}
+
+void NamespaceSupport::setTargetNamespace(const QXmlName::NamespaceCode namespaceCode)
+{
+ m_ns.insert(0, namespaceCode);
+}
+
+QXmlName::PrefixCode NamespaceSupport::prefix(const QXmlName::NamespaceCode namespaceCode) const
+{
+ NamespaceHash::const_iterator itc, it = m_ns.constBegin();
+ while ((itc=it) != m_ns.constEnd()) {
+ ++it;
+ if (*itc == namespaceCode)
+ return itc.key();
+ }
+ return 0;
+}
+
+QXmlName::NamespaceCode NamespaceSupport::uri(const QXmlName::PrefixCode prefixCode) const
+{
+ return m_ns.value(prefixCode);
+}
+
+bool NamespaceSupport::processName(const QString& qname, NameType type, QXmlName &name) const
+{
+ int len = qname.size();
+ const QChar *data = qname.constData();
+ for (int pos = 0; pos < len; ++pos) {
+ if (data[pos] == QLatin1Char(':')) {
+ const QXmlName::PrefixCode prefixCode = m_namePool->allocatePrefix(qname.left(pos));
+ if (!m_ns.contains(prefixCode))
+ return false;
+ const QXmlName::NamespaceCode namespaceCode = uri(prefixCode);
+ const QXmlName::LocalNameCode localNameCode = m_namePool->allocateLocalName(qname.mid(pos + 1));
+ name = QXmlName(namespaceCode, localNameCode, prefixCode);
+ return true;
+ }
+ }
+
+ // there was no ':'
+ QXmlName::NamespaceCode namespaceCode = 0;
+ // attributes don't take default namespace
+ if (type == ElementName && !m_ns.isEmpty()) {
+ namespaceCode = m_ns.value(0); // get default namespace
+ }
+
+ const QXmlName::LocalNameCode localNameCode = m_namePool->allocateLocalName(qname);
+ name = QXmlName(namespaceCode, localNameCode, 0);
+
+ return true;
+}
+
+void NamespaceSupport::pushContext()
+{
+ m_nsStack.push(m_ns);
+}
+
+void NamespaceSupport::popContext()
+{
+ m_ns.clear();
+ if(!m_nsStack.isEmpty())
+ m_ns = m_nsStack.pop();
+}
+
+QList<QXmlName> NamespaceSupport::namespaceBindings() const
+{
+ QList<QXmlName> bindings;
+
+ QHashIterator<QXmlName::PrefixCode, QXmlName::NamespaceCode> it(m_ns);
+ while (it.hasNext()) {
+ it.next();
+ bindings.append(QXmlName(it.value(), StandardLocalNames::empty, it.key()));
+ }
+
+ return bindings;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qnamespacesupport_p.h b/src/xmlpatterns/schema/qnamespacesupport_p.h
new file mode 100644
index 0000000..2a2cb1e
--- /dev/null
+++ b/src/xmlpatterns/schema/qnamespacesupport_p.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_NamespaceSupport_H
+#define Patternist_NamespaceSupport_H
+
+#include "qnamepool_p.h"
+
+#include <QtCore/QExplicitlySharedDataPointer>
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+#include <QtCore/QStack>
+#include <QtCore/QXmlStreamNamespaceDeclarations>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class for handling nested namespace declarations.
+ *
+ * This class is mostly an adaption of QXmlNamespaceSupport to the NamePool
+ * mechanism used in XmlPatterns.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class NamespaceSupport
+ {
+ public:
+ /**
+ * Describes whether the name to process is an attribute or element.
+ */
+ enum NameType
+ {
+ AttributeName, ///< An attribute name to process.
+ ElementName ///< An element name to process.
+ };
+
+ /**
+ * Creates an empty namespace support object.
+ */
+ NamespaceSupport();
+
+ /**
+ * Creates a new namespace support object.
+ *
+ * @param namePool The name pool where all processed names are stored in.
+ */
+ NamespaceSupport(const NamePool::Ptr &namePool);
+
+ /**
+ * Adds a new prefix-to-namespace binding.
+ *
+ * @param prefixCode The name pool code for the prefix.
+ * @param namespaceCode The name pool code for the namespace.
+ */
+ void setPrefix(const QXmlName::PrefixCode prefixCode, const QXmlName::NamespaceCode namespaceCode);
+
+ /**
+ * Adds the prefix-to-namespace bindings from @p declarations to
+ * the namespace support.
+ */
+ void setPrefixes(const QXmlStreamNamespaceDeclarations &declarations);
+
+ /**
+ * Sets the name pool code of the target namespace of the schema the
+ * namespace support works on.
+ */
+ void setTargetNamespace(const QXmlName::NamespaceCode code);
+
+ /**
+ * Returns the prefix code for the given namespace @p code.
+ */
+ QXmlName::PrefixCode prefix(const QXmlName::NamespaceCode code) const;
+
+ /**
+ * Returns the namespace code for the given prefix @p code.
+ */
+ QXmlName::NamespaceCode uri(const QXmlName::PrefixCode code) const;
+
+ /**
+ * Converts the given @p qualifiedName to a resolved QXmlName @p name according
+ * to the current namespace mapping.
+ *
+ * @param qualifiedName The full qualified name.
+ * @param type The type of name processing.
+ * @param name The resolved QXmlName.
+ *
+ * @returns @c true if the name could be processed correctly or @c false if the
+ * namespace prefix is unknown.
+ */
+ bool processName(const QString &qualifiedName, NameType type, QXmlName &name) const;
+
+ /**
+ * Pushes the current namespace mapping onto the stack.
+ */
+ void pushContext();
+
+ /**
+ * Pops the current namespace mapping from the stack.
+ */
+ void popContext();
+
+ /**
+ * Returns the list of namespace bindings.
+ */
+ QList<QXmlName> namespaceBindings() const;
+
+ private:
+ typedef QHash<QXmlName::PrefixCode, QXmlName::NamespaceCode> NamespaceHash;
+
+ NamePool::Ptr m_namePool;
+ QStack<NamespaceHash> m_nsStack;
+ NamespaceHash m_ns;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdalternative.cpp b/src/xmlpatterns/schema/qxsdalternative.cpp
new file mode 100644
index 0000000..279a184
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdalternative.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdalternative_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAlternative::setTest(const XsdXPathExpression::Ptr &test)
+{
+ m_test = test;
+}
+
+XsdXPathExpression::Ptr XsdAlternative::test() const
+{
+ return m_test;
+}
+
+void XsdAlternative::setType(const SchemaType::Ptr &type)
+{
+ m_type = type;
+}
+
+SchemaType::Ptr XsdAlternative::type() const
+{
+ return m_type;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdalternative_p.h b/src/xmlpatterns/schema/qxsdalternative_p.h
new file mode 100644
index 0000000..f94f0ac
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdalternative_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdAlternative_H
+#define Patternist_XsdAlternative_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qschematype_p.h"
+#include "qxsdannotated_p.h"
+#include "qxsdxpathexpression_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD alternative object.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAlternative : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAlternative> Ptr;
+ typedef QList<XsdAlternative::Ptr> List;
+
+ /**
+ * Sets the xpath @p test of the alternative.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#tac-test">Test Definition</a>
+ */
+ void setTest(const XsdXPathExpression::Ptr &test);
+
+ /**
+ * Returns the xpath test of the alternative.
+ */
+ XsdXPathExpression::Ptr test() const;
+
+ /**
+ * Sets the @p type of the alternative.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#tac-type_definition">Type Definition</a>
+ */
+ void setType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the type of the alternative.
+ */
+ SchemaType::Ptr type() const;
+
+ private:
+ XsdXPathExpression::Ptr m_test;
+ SchemaType::Ptr m_type;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdannotated.cpp b/src/xmlpatterns/schema/qxsdannotated.cpp
new file mode 100644
index 0000000..151057d
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdannotated.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdannotated_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAnnotated::addAnnotation(const XsdAnnotation::Ptr &annotation)
+{
+ m_annotations.append(annotation);
+}
+
+void XsdAnnotated::addAnnotations(const XsdAnnotation::List &annotations)
+{
+ m_annotations << annotations;
+}
+
+XsdAnnotation::List XsdAnnotated::annotations() const
+{
+ return m_annotations;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdannotated_p.h b/src/xmlpatterns/schema/qxsdannotated_p.h
new file mode 100644
index 0000000..f8d7fe1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdannotated_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdAnnotated_H
+#define Patternist_XsdAnnotated_H
+
+#include "qxsdannotation_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for all XSD components with annotation content.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAnnotated
+ {
+ public:
+ /**
+ * Adds a new @p annotation to the component.
+ */
+ void addAnnotation(const XsdAnnotation::Ptr &annotation);
+
+ /**
+ * Adds a list of new @p annotations to the component.
+ */
+ void addAnnotations(const XsdAnnotation::List &annotations);
+
+ /**
+ * Returns the list of all annotations of the component.
+ */
+ XsdAnnotation::List annotations() const;
+
+ private:
+ XsdAnnotation::List m_annotations;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdannotation.cpp b/src/xmlpatterns/schema/qxsdannotation.cpp
new file mode 100644
index 0000000..9c76378
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdannotation.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdannotation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAnnotation::setId(const DerivedString<TypeID>::Ptr &id)
+{
+ m_id = id;
+}
+
+DerivedString<TypeID>::Ptr XsdAnnotation::id() const
+{
+ return m_id;
+}
+
+void XsdAnnotation::addApplicationInformation(const XsdApplicationInformation::Ptr &information)
+{
+ m_applicationInformation.append(information);
+}
+
+XsdApplicationInformation::List XsdAnnotation::applicationInformation() const
+{
+ return m_applicationInformation;
+}
+
+void XsdAnnotation::addDocumentation(const XsdDocumentation::Ptr &documentation)
+{
+ m_documentations.append(documentation);
+}
+
+XsdDocumentation::List XsdAnnotation::documentation() const
+{
+ return m_documentations;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdannotation_p.h b/src/xmlpatterns/schema/qxsdannotation_p.h
new file mode 100644
index 0000000..a8e2d55
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdannotation_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdAnnotation_H
+#define Patternist_XsdAnnotation_H
+
+#include "qderivedstring_p.h"
+#include "qxsdapplicationinformation_p.h"
+#include "qxsddocumentation_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD annotation object.
+ *
+ * This class represents the <em>annotation</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cAnnotations">here</a>.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAnnotation : public NamedSchemaComponent
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAnnotation> Ptr;
+ typedef QList<XsdAnnotation::Ptr> List;
+
+ /**
+ * Sets the @p id of the annotation.
+ */
+ void setId(const DerivedString<TypeID>::Ptr &id);
+
+ /**
+ * Returns the @p id of the annotation.
+ */
+ DerivedString<TypeID>::Ptr id() const;
+
+ /**
+ * Adds an application @p information to the annotation.
+ *
+ * The application information is meant to be interpreted by
+ * a software system, e.g. other parts of the XML processor pipeline.
+ */
+ void addApplicationInformation(const XsdApplicationInformation::Ptr &information);
+
+ /**
+ * Returns the list of all application information of the annotation.
+ */
+ XsdApplicationInformation::List applicationInformation() const;
+
+ /**
+ * Adds a @p documentation to the annotation.
+ *
+ * The documentation is meant to be read by human being, e.g. additional
+ * constraints or information about schema components.
+ */
+ void addDocumentation(const XsdDocumentation::Ptr &documentation);
+
+ /**
+ * Returns the list of all documentations of the annotation.
+ */
+ XsdDocumentation::List documentation() const;
+
+ private:
+ DerivedString<TypeID>::Ptr m_id;
+ XsdApplicationInformation::List m_applicationInformation;
+ XsdDocumentation::List m_documentations;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdapplicationinformation.cpp b/src/xmlpatterns/schema/qxsdapplicationinformation.cpp
new file mode 100644
index 0000000..45c6391
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdapplicationinformation.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdapplicationinformation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdApplicationInformation::setSource(const AnyURI::Ptr &source)
+{
+ m_source = source;
+}
+
+AnyURI::Ptr XsdApplicationInformation::source() const
+{
+ return m_source;
+}
+
+void XsdApplicationInformation::setContent(const QString &content)
+{
+ m_content = content;
+}
+
+QString XsdApplicationInformation::content() const
+{
+ return m_content;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdapplicationinformation_p.h b/src/xmlpatterns/schema/qxsdapplicationinformation_p.h
new file mode 100644
index 0000000..1a549cb
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdapplicationinformation_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdApplicationInformation_H
+#define Patternist_XsdApplicationInformation_H
+
+#include "qanytype_p.h"
+#include "qanyuri_p.h"
+#include "qnamedschemacomponent_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD appinfo object.
+ *
+ * This class represents the <em>appinfo</em> component of an <em>annotation</em> object
+ * of a XML schema as described <a href="http://www.w3.org/TR/xmlschema11-1/#cAnnotations">here</a>.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdApplicationInformation : public NamedSchemaComponent
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdApplicationInformation> Ptr;
+ typedef QList<XsdApplicationInformation::Ptr> List;
+
+ /**
+ * Sets the @p source of the application information.
+ *
+ * The source points to an URL that contains more
+ * information.
+ */
+ void setSource(const AnyURI::Ptr &source);
+
+ /**
+ * Returns the source of the application information.
+ */
+ AnyURI::Ptr source() const;
+
+ /**
+ * Sets the @p content of the application information.
+ *
+ * The content can be of abritrary type.
+ */
+ void setContent(const QString &content);
+
+ /**
+ * Returns the content of the application information.
+ */
+ QString content() const;
+
+ private:
+ AnyURI::Ptr m_source;
+ QString m_content;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdassertion.cpp b/src/xmlpatterns/schema/qxsdassertion.cpp
new file mode 100644
index 0000000..2f2d8aa
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdassertion.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdassertion_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAssertion::setTest(const XsdXPathExpression::Ptr &test)
+{
+ m_test = test;
+}
+
+XsdXPathExpression::Ptr XsdAssertion::test() const
+{
+ return m_test;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdassertion_p.h b/src/xmlpatterns/schema/qxsdassertion_p.h
new file mode 100644
index 0000000..c511c85
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdassertion_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdAssertion_H
+#define Patternist_XsdAssertion_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+#include "qxsdxpathexpression_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD assertion object.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#cAssertions">Assertion Definition</a>
+ */
+ class XsdAssertion : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAssertion> Ptr;
+ typedef QList<XsdAssertion::Ptr> List;
+
+ /**
+ * Sets the @p test of the assertion.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#as-test">Test Definition</a>
+ */
+ void setTest(const XsdXPathExpression::Ptr &test);
+
+ /**
+ * Returns the test of the assertion.
+ */
+ XsdXPathExpression::Ptr test() const;
+
+ private:
+ XsdXPathExpression::Ptr m_test;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdattribute.cpp b/src/xmlpatterns/schema/qxsdattribute.cpp
new file mode 100644
index 0000000..68f9e3d
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattribute.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdattribute_p.h"
+#include "qxsdcomplextype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+
+void XsdAttribute::Scope::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdAttribute::Scope::Variety XsdAttribute::Scope::variety() const
+{
+ return m_variety;
+}
+
+void XsdAttribute::Scope::setParent(const NamedSchemaComponent::Ptr &parent)
+{
+ m_parent = parent;
+}
+
+NamedSchemaComponent::Ptr XsdAttribute::Scope::parent() const
+{
+ return m_parent;
+}
+
+void XsdAttribute::ValueConstraint::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdAttribute::ValueConstraint::Variety XsdAttribute::ValueConstraint::variety() const
+{
+ return m_variety;
+}
+
+void XsdAttribute::ValueConstraint::setValue(const QString &value)
+{
+ m_value = value;
+}
+
+QString XsdAttribute::ValueConstraint::value() const
+{
+ return m_value;
+}
+
+void XsdAttribute::ValueConstraint::setLexicalForm(const QString &form)
+{
+ m_lexicalForm = form;
+}
+
+QString XsdAttribute::ValueConstraint::lexicalForm() const
+{
+ return m_lexicalForm;
+}
+
+void XsdAttribute::setType(const AnySimpleType::Ptr &type)
+{
+ m_type = type;
+}
+
+AnySimpleType::Ptr XsdAttribute::type() const
+{
+ return m_type;
+}
+
+void XsdAttribute::setScope(const Scope::Ptr &scope)
+{
+ m_scope = scope;
+}
+
+XsdAttribute::Scope::Ptr XsdAttribute::scope() const
+{
+ return m_scope;
+}
+
+void XsdAttribute::setValueConstraint(const ValueConstraint::Ptr &constraint)
+{
+ m_valueConstraint = constraint;
+}
+
+XsdAttribute::ValueConstraint::Ptr XsdAttribute::valueConstraint() const
+{
+ return m_valueConstraint;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdattribute_p.h b/src/xmlpatterns/schema/qxsdattribute_p.h
new file mode 100644
index 0000000..d64d335
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattribute_p.h
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdAttribute_H
+#define Patternist_XsdAttribute_H
+
+#include "qanysimpletype_p.h"
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD attribute object.
+ *
+ * This class represents the <em>attribute</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cAttribute_Declarations">here</a>.
+ *
+ * It contains information from either a top-level attribute declaration (as child of
+ * a <em>schema</em> object) or of a local attribute declaration (as child of <em>complexType</em>
+ * or <em>attributeGroup</em> object without a 'ref' attribute).
+ *
+ * All other occurrences of the <em>attribute</em> object are represented by the XsdAttributeUse class.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSAttributeDeclaration">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAttribute : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAttribute> Ptr;
+ typedef QList<XsdAttribute::Ptr> List;
+
+ /**
+ * @short Describes the scope of an attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#sc_a">Scope Definition</a>
+ */
+ class Scope : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<Scope> Ptr;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ad-scope">scope</a> of an attribute.
+ */
+ enum Variety
+ {
+ Global, ///< The attribute is defined globally as child of the <em>schema</em> object.
+ Local ///< The attribute is defined locally as child of a complex type or attribute group definition.
+ };
+
+ /**
+ * Sets the @p variety of the attribute scope.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#sc_a-variety">Variety Definition</a>
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the attribute scope.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p parent complex type or attribute group definition of the attribute scope.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#sc_a-parent">Parent Definition</a>
+ */
+ void setParent(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * Returns the parent complex type or attribute group definition of the attribute scope.
+ */
+ NamedSchemaComponent::Ptr parent() const;
+
+ private:
+ Variety m_variety;
+ NamedSchemaComponent::Ptr m_parent;
+ };
+
+
+ /**
+ * @short Describes the value constraint of an attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_a">Value Constraint Definition</a>
+ */
+ class ValueConstraint : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ValueConstraint> Ptr;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ad-value_constraint">value constraint</a> of an attribute.
+ */
+ enum Variety
+ {
+ Default, ///< The attribute has a default value set.
+ Fixed ///< The attribute has a fixed value set.
+ };
+
+ /**
+ * Sets the @p variety of the attribute value constraint.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_a-variety">Variety Definition</a>
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the attribute value constraint.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p value of the constraint.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_a-value">Value Definition</a>
+ */
+ void setValue(const QString &value);
+
+ /**
+ * Returns the value of the constraint.
+ */
+ QString value() const;
+
+ /**
+ * Sets the lexical @p form of the constraint.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_a-lexical_form">Lexical Form Definition</a>
+ */
+ void setLexicalForm(const QString &form);
+
+ /**
+ * Returns the lexical form of the constraint.
+ */
+ QString lexicalForm() const;
+
+ private:
+ Variety m_variety;
+ QString m_value;
+ QString m_lexicalForm;
+ };
+
+ /**
+ * Sets the simple @p type definition of the attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ad-type_definition">Simple Type Definition</a>
+ */
+ void setType(const AnySimpleType::Ptr &type);
+
+ /**
+ * Returns the simple type definition of the attribute.
+ */
+ AnySimpleType::Ptr type() const;
+
+ /**
+ * Sets the @p scope of the attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ad-scope">Scope Definition</a>
+ */
+ void setScope(const Scope::Ptr &scope);
+
+ /**
+ * Returns the scope of the attribute.
+ */
+ Scope::Ptr scope() const;
+
+ /**
+ * Sets the value @p constraint of the attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ad-value_constraint">Value Constraint Definition</a>
+ */
+ void setValueConstraint(const ValueConstraint::Ptr &constraint);
+
+ /**
+ * Returns the value constraint of the attribute.
+ */
+ ValueConstraint::Ptr valueConstraint() const;
+
+ private:
+ AnySimpleType::Ptr m_type;
+ Scope::Ptr m_scope;
+ ValueConstraint::Ptr m_valueConstraint;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdattributegroup.cpp b/src/xmlpatterns/schema/qxsdattributegroup.cpp
new file mode 100644
index 0000000..b0dbc8a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributegroup.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdattributegroup_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAttributeGroup::setAttributeUses(const XsdAttributeUse::List &attributeUses)
+{
+ m_attributeUses = attributeUses;
+}
+
+void XsdAttributeGroup::addAttributeUse(const XsdAttributeUse::Ptr &attributeUse)
+{
+ m_attributeUses.append(attributeUse);
+}
+
+XsdAttributeUse::List XsdAttributeGroup::attributeUses() const
+{
+ return m_attributeUses;
+}
+
+void XsdAttributeGroup::setWildcard(const XsdWildcard::Ptr &wildcard)
+{
+ m_wildcard = wildcard;
+}
+
+XsdWildcard::Ptr XsdAttributeGroup::wildcard() const
+{
+ return m_wildcard;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdattributegroup_p.h b/src/xmlpatterns/schema/qxsdattributegroup_p.h
new file mode 100644
index 0000000..0d76d53
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributegroup_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdAttributeGroup_H
+#define Patternist_XsdAttributeGroup_H
+
+#include "qxsdannotated_p.h"
+#include "qxsdattributeuse_p.h"
+#include "qxsdwildcard_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents the XSD attributeGroup object.
+ *
+ * This class represents the <em>attributeGroup</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cAttribute_Group_Definitions">here</a>.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSAttributeGroup">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAttributeGroup : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAttributeGroup> Ptr;
+ typedef QList<XsdAttributeGroup::Ptr> List;
+
+ /**
+ * Sets the list of attribute @p uses that are defined in the attribute group.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#agd-attribute_uses">Attribute Uses</a>
+ */
+ void setAttributeUses(const XsdAttributeUse::List &uses);
+
+ /**
+ * Adds a new attribute @p use to the attribute group.
+ */
+ void addAttributeUse(const XsdAttributeUse::Ptr &use);
+
+ /**
+ * Returns the list of all attribute uses of the attribute group.
+ */
+ XsdAttributeUse::List attributeUses() const;
+
+ /**
+ * Sets the attribute @p wildcard of the attribute group.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#agd-attribute_wildcard">Attribute Wildcard</a>
+ */
+ void setWildcard(const XsdWildcard::Ptr &wildcard);
+
+ /**
+ * Returns the attribute wildcard of the attribute group.
+ */
+ XsdWildcard::Ptr wildcard() const;
+
+ private:
+ XsdAttributeUse::List m_attributeUses;
+ XsdWildcard::Ptr m_wildcard;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdattributereference.cpp b/src/xmlpatterns/schema/qxsdattributereference.cpp
new file mode 100644
index 0000000..853705a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributereference.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdattributereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XsdAttributeReference::isAttributeUse() const
+{
+ return false;
+}
+
+bool XsdAttributeReference::isReference() const
+{
+ return true;
+}
+
+void XsdAttributeReference::setType(Type type)
+{
+ m_type = type;
+}
+
+XsdAttributeReference::Type XsdAttributeReference::type() const
+{
+ return m_type;
+}
+
+void XsdAttributeReference::setReferenceName(const QXmlName &referenceName)
+{
+ m_referenceName = referenceName;
+}
+
+QXmlName XsdAttributeReference::referenceName() const
+{
+ return m_referenceName;
+}
+
+void XsdAttributeReference::setSourceLocation(const QSourceLocation &location)
+{
+ m_sourceLocation = location;
+}
+
+QSourceLocation XsdAttributeReference::sourceLocation() const
+{
+ return m_sourceLocation;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdattributereference_p.h b/src/xmlpatterns/schema/qxsdattributereference_p.h
new file mode 100644
index 0000000..9c3ef80
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributereference_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdAttributeReference_H
+#define Patternist_XsdAttributeReference_H
+
+#include "qxsdattributeuse_p.h"
+
+#include <QtXmlPatterns/QSourceLocation>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class for attribute reference resolving.
+ *
+ * For easy resolving of attribute references, we have this class
+ * that can be used as a place holder for the real attribute use
+ * object it is referring to.
+ * So whenever the parser detects an attribute reference, it creates
+ * a XsdAttributeReference and returns it instead of the XsdAttributeUse.
+ * During a later phase, the resolver will look for all XsdAttributeReferences
+ * in the schema and will replace them with their referring XsdAttributeUse
+ * objects.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAttributeReference : public XsdAttributeUse
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAttributeReference> Ptr;
+
+ /**
+ * Describes the type of the attribute reference.
+ */
+ enum Type
+ {
+ AttributeUse, ///< The reference points to an attribute use.
+ AttributeGroup ///< The reference points to an attribute group.
+ };
+
+ /**
+ * Always returns false, used to avoid dynamic casts.
+ */
+ virtual bool isAttributeUse() const;
+
+ /**
+ * Always returns true, used to avoid dynamic casts.
+ */
+ virtual bool isReference() const;
+
+ /**
+ * Sets the @p type of the attribute reference.
+ */
+ void setType(Type type);
+
+ /**
+ * Returns the type of the attribute reference.
+ */
+ Type type() const;
+
+ /**
+ * Sets the @p name of the attribute or attribute group the
+ * attribute reference refers to.
+ */
+ void setReferenceName(const QXmlName &name);
+
+ /**
+ * Returns the name of the attribute or attribute group the
+ * attribute reference refers to.
+ */
+ QXmlName referenceName() const;
+
+ /**
+ * Sets the source @p location where the reference is located.
+ */
+ void setSourceLocation(const QSourceLocation &location);
+
+ /**
+ * Returns the source location where the reference is located.
+ */
+ QSourceLocation sourceLocation() const;
+
+ private:
+ Type m_type;
+ QXmlName m_referenceName;
+ QSourceLocation m_sourceLocation;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdattributeterm.cpp b/src/xmlpatterns/schema/qxsdattributeterm.cpp
new file mode 100644
index 0000000..afed862
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributeterm.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdattributeterm_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XsdAttributeTerm::isAttributeUse() const
+{
+ return false;
+}
+
+bool XsdAttributeTerm::isReference() const
+{
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdattributeterm_p.h b/src/xmlpatterns/schema/qxsdattributeterm_p.h
new file mode 100644
index 0000000..45f5402
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributeterm_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdAttributeTerm_H
+#define Patternist_XsdAttributeTerm_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A base class for all attribute types.
+ *
+ * For easy resolving of attribute references, we use this as
+ * common base class for XsdAttribute and XsdAttributeReference.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAttributeTerm : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAttributeTerm> Ptr;
+
+ /**
+ * Returns @c true if the term is an attribute use, @c false otherwise.
+ */
+ virtual bool isAttributeUse() const;
+
+ /**
+ * Returns @c true if the term is an attribute use reference, @c false otherwise.
+ *
+ * @note The reference term is only used internally as helper during type resolving.
+ */
+ virtual bool isReference() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdattributeuse.cpp b/src/xmlpatterns/schema/qxsdattributeuse.cpp
new file mode 100644
index 0000000..4055d48
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributeuse.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdattributeuse_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdAttributeUse::ValueConstraint::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdAttributeUse::ValueConstraint::Variety XsdAttributeUse::ValueConstraint::variety() const
+{
+ return m_variety;
+}
+
+void XsdAttributeUse::ValueConstraint::setValue(const QString &value)
+{
+ m_value = value;
+}
+
+QString XsdAttributeUse::ValueConstraint::value() const
+{
+ return m_value;
+}
+
+void XsdAttributeUse::ValueConstraint::setLexicalForm(const QString &form)
+{
+ m_lexicalForm = form;
+}
+
+QString XsdAttributeUse::ValueConstraint::lexicalForm() const
+{
+ return m_lexicalForm;
+}
+
+XsdAttributeUse::ValueConstraint::Ptr XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(const XsdAttribute::ValueConstraint::Ptr &constraint)
+{
+ XsdAttributeUse::ValueConstraint::Ptr newConstraint(new XsdAttributeUse::ValueConstraint());
+ switch (constraint->variety()) {
+ case XsdAttribute::ValueConstraint::Fixed: newConstraint->setVariety(Fixed); break;
+ case XsdAttribute::ValueConstraint::Default: newConstraint->setVariety(Default); break;
+ }
+ newConstraint->setValue(constraint->value());
+ newConstraint->setLexicalForm(constraint->lexicalForm());
+
+ return newConstraint;
+}
+
+XsdAttributeUse::XsdAttributeUse()
+ : m_useType(OptionalUse)
+{
+}
+
+bool XsdAttributeUse::isAttributeUse() const
+{
+ return true;
+}
+
+void XsdAttributeUse::setUseType(UseType type)
+{
+ m_useType = type;
+}
+
+XsdAttributeUse::UseType XsdAttributeUse::useType() const
+{
+ return m_useType;
+}
+
+bool XsdAttributeUse::isRequired() const
+{
+ return (m_useType == RequiredUse);
+}
+
+void XsdAttributeUse::setAttribute(const XsdAttribute::Ptr &attribute)
+{
+ m_attribute = attribute;
+}
+
+XsdAttribute::Ptr XsdAttributeUse::attribute() const
+{
+ return m_attribute;
+}
+
+void XsdAttributeUse::setValueConstraint(const ValueConstraint::Ptr &constraint)
+{
+ m_valueConstraint = constraint;
+}
+
+XsdAttributeUse::ValueConstraint::Ptr XsdAttributeUse::valueConstraint() const
+{
+ return m_valueConstraint;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdattributeuse_p.h b/src/xmlpatterns/schema/qxsdattributeuse_p.h
new file mode 100644
index 0000000..648620f
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdattributeuse_p.h
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdAttributeUse_H
+#define Patternist_XsdAttributeUse_H
+
+#include "qxsdattribute_p.h"
+#include "qxsdattributeterm_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD attribute use object.
+ *
+ * This class represents the <em>attribute use</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cAttributeUse">here</a>.
+ *
+ * It contains information from a local attribute declaration (as child of <em>complexType</em>
+ * or <em>attributeGroup</em> object).
+ *
+ * All other occurrences of the <em>attribute</em> object are represented by the XsdAttribute class.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSAttributeUse">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdAttributeUse : public XsdAttributeTerm
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdAttributeUse> Ptr;
+ typedef QList<XsdAttributeUse::Ptr> List;
+
+ /**
+ * Describes the value constraint of an attribute use.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_au">Value Constraint Definition</a>
+ */
+ class ValueConstraint : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ValueConstraint> Ptr;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#au-value_constraint">value constraint</a> of an attribute use.
+ */
+ enum Variety
+ {
+ Default, ///< The attribute use has a default value set.
+ Fixed ///< The attribute use has a fixed value set.
+ };
+
+ /**
+ * Sets the @p variety of the attribute use value constraint.
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the attribute use value constraint.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p value of the constraint.
+ */
+ void setValue(const QString &value);
+
+ /**
+ * Returns the value of the constraint.
+ */
+ QString value() const;
+
+ /**
+ * Sets the lexical @p form of the constraint.
+ */
+ void setLexicalForm(const QString &form);
+
+ /**
+ * Returns the lexical form of the constraint.
+ */
+ QString lexicalForm() const;
+
+ /**
+ * Creates a new value constraint from a XsdAttribute::ValueConstraint.
+ */
+ static ValueConstraint::Ptr fromAttributeValueConstraint(const XsdAttribute::ValueConstraint::Ptr &constraint);
+
+ private:
+ Variety m_variety;
+ QString m_value;
+ QString m_lexicalForm;
+ };
+
+ /**
+ * Describes the use type of the attribute use.
+ */
+ enum UseType
+ {
+ OptionalUse, ///< The attribute can be there but doesn't need to.
+ RequiredUse, ///< The attribute must be there.
+ ProhibitedUse ///< The attribute is not allowed to be there.
+ };
+
+ /**
+ * Creates a new attribute use object.
+ */
+ XsdAttributeUse();
+
+ /**
+ * Always returns true, used to avoid dynamic casts.
+ */
+ virtual bool isAttributeUse() const;
+
+ /**
+ * Sets the use @p type of the attribute use.
+ *
+ * @see UseType
+ */
+ void setUseType(UseType type);
+
+ /**
+ * Returns the use type of the attribute use.
+ */
+ UseType useType() const;
+
+ /**
+ * Returns whether the attribute use is required.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#au-required">Required Definition</a>
+ */
+ bool isRequired() const;
+
+ /**
+ * Sets the @p attribute the attribute use is referring to.
+ * That is either a local definition as child of a complexType
+ * or attributeGroup object, or a reference defined by the
+ * 'ref' attribute.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#au-attribute_declaration">Attribute Declaration</a>
+ */
+ void setAttribute(const XsdAttribute::Ptr &attribute);
+
+ /**
+ * Returns the attribute the attribute use is referring to.
+ */
+ XsdAttribute::Ptr attribute() const;
+
+ /**
+ * Sets the value @p constraint of the attribute use.
+ *
+ * @see http://www.w3.org/TR/xmlschema11-1/#vc_au
+ */
+ void setValueConstraint(const ValueConstraint::Ptr &constraint);
+
+ /**
+ * Returns the value constraint of the attribute use.
+ */
+ ValueConstraint::Ptr valueConstraint() const;
+
+ private:
+ UseType m_useType;
+ XsdAttribute::Ptr m_attribute;
+ ValueConstraint::Ptr m_valueConstraint;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdcomplextype.cpp b/src/xmlpatterns/schema/qxsdcomplextype.cpp
new file mode 100644
index 0000000..42aeb60
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdcomplextype.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdcomplextype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdComplexType::OpenContent::setMode(Mode mode)
+{
+ m_mode = mode;
+}
+
+XsdComplexType::OpenContent::Mode XsdComplexType::OpenContent::mode() const
+{
+ return m_mode;
+}
+
+void XsdComplexType::OpenContent::setWildcard(const XsdWildcard::Ptr &wildcard)
+{
+ m_wildcard = wildcard;
+}
+
+XsdWildcard::Ptr XsdComplexType::OpenContent::wildcard() const
+{
+ return m_wildcard;
+}
+
+void XsdComplexType::ContentType::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdComplexType::ContentType::Variety XsdComplexType::ContentType::variety() const
+{
+ return m_variety;
+}
+
+void XsdComplexType::ContentType::setParticle(const XsdParticle::Ptr &particle)
+{
+ m_particle = particle;
+}
+
+XsdParticle::Ptr XsdComplexType::ContentType::particle() const
+{
+ return m_particle;
+}
+
+void XsdComplexType::ContentType::setOpenContent(const OpenContent::Ptr &content)
+{
+ m_openContent = content;
+}
+
+XsdComplexType::OpenContent::Ptr XsdComplexType::ContentType::openContent() const
+{
+ return m_openContent;
+}
+
+void XsdComplexType::ContentType::setSimpleType(const AnySimpleType::Ptr &type)
+{
+ m_simpleType = type;
+}
+
+AnySimpleType::Ptr XsdComplexType::ContentType::simpleType() const
+{
+ return m_simpleType;
+}
+
+
+XsdComplexType::XsdComplexType()
+ : m_isAbstract(false)
+ , m_contentType(new ContentType())
+{
+ m_contentType->setVariety(ContentType::Empty);
+}
+
+void XsdComplexType::setIsAbstract(bool abstract)
+{
+ m_isAbstract = abstract;
+}
+
+bool XsdComplexType::isAbstract() const
+{
+ return m_isAbstract;
+}
+
+QString XsdComplexType::displayName(const NamePool::Ptr &np) const
+{
+ return np->displayName(name(np));
+}
+
+void XsdComplexType::setWxsSuperType(const SchemaType::Ptr &type)
+{
+ m_superType = type;
+}
+
+SchemaType::Ptr XsdComplexType::wxsSuperType() const
+{
+ return m_superType;
+}
+
+void XsdComplexType::setContext(const NamedSchemaComponent::Ptr &component)
+{
+ m_context = component;
+}
+
+NamedSchemaComponent::Ptr XsdComplexType::context() const
+{
+ return m_context;
+}
+
+void XsdComplexType::setContentType(const ContentType::Ptr &type)
+{
+ m_contentType = type;
+}
+
+XsdComplexType::ContentType::Ptr XsdComplexType::contentType() const
+{
+ return m_contentType;
+}
+
+void XsdComplexType::setAttributeUses(const XsdAttributeUse::List &attributeUses)
+{
+ m_attributeUses = attributeUses;
+}
+
+void XsdComplexType::addAttributeUse(const XsdAttributeUse::Ptr &attributeUse)
+{
+ m_attributeUses.append(attributeUse);
+}
+
+XsdAttributeUse::List XsdComplexType::attributeUses() const
+{
+ return m_attributeUses;
+}
+
+void XsdComplexType::setAttributeWildcard(const XsdWildcard::Ptr &wildcard)
+{
+ m_attributeWildcard = wildcard;
+}
+
+XsdWildcard::Ptr XsdComplexType::attributeWildcard() const
+{
+ return m_attributeWildcard;
+}
+
+XsdComplexType::TypeCategory XsdComplexType::category() const
+{
+ return ComplexType;
+}
+
+void XsdComplexType::setDerivationMethod(DerivationMethod method)
+{
+ m_derivationMethod = method;
+}
+
+XsdComplexType::DerivationMethod XsdComplexType::derivationMethod() const
+{
+ return m_derivationMethod;
+}
+
+void XsdComplexType::setProhibitedSubstitutions(const BlockingConstraints &substitutions)
+{
+ m_prohibitedSubstitutions = substitutions;
+}
+
+XsdComplexType::BlockingConstraints XsdComplexType::prohibitedSubstitutions() const
+{
+ return m_prohibitedSubstitutions;
+}
+
+void XsdComplexType::setAssertions(const XsdAssertion::List &assertions)
+{
+ m_assertions = assertions;
+}
+
+void XsdComplexType::addAssertion(const XsdAssertion::Ptr &assertion)
+{
+ m_assertions.append(assertion);
+}
+
+XsdAssertion::List XsdComplexType::assertions() const
+{
+ return m_assertions;
+}
+
+bool XsdComplexType::isDefinedBySchema() const
+{
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdcomplextype_p.h b/src/xmlpatterns/schema/qxsdcomplextype_p.h
new file mode 100644
index 0000000..d28d2fc
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdcomplextype_p.h
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdComplexType_H
+#define Patternist_XsdComplexType_H
+
+#include "qanytype_p.h"
+#include "qxsdassertion_p.h"
+#include "qxsdattributeuse_p.h"
+#include "qxsdparticle_p.h"
+#include "qxsdsimpletype_p.h"
+#include "qxsduserschematype_p.h"
+#include "qxsdwildcard_p.h"
+
+#include <QtCore/QSet>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD complexType object.
+ *
+ * This class represents the <em>complexType</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#Complex_Type_Definitions">here</a>.
+ *
+ * It contains information from either a top-level complex type declaration (as child of a <em>schema</em> object)
+ * or a local complex type declaration (as descendant of an <em>element</em> object).
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSComplexType">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdComplexType : public XsdUserSchemaType<AnyType>
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdComplexType> Ptr;
+
+ /**
+ * @short Describes the open content object of a complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ct-open_content">Open Content Definition</a>
+ */
+ class OpenContent : public QSharedData, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<OpenContent> Ptr;
+
+ /**
+ * Describes the mode of the open content.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#oc-mode">Mode Definition</a>
+ */
+ enum Mode
+ {
+ None,
+ Interleave,
+ Suffix
+ };
+
+ /**
+ * Sets the @p mode of the open content.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#oc-mode">Mode Definition</a>
+ */
+ void setMode(Mode mode);
+
+ /**
+ * Returns the mode of the open content.
+ */
+ Mode mode() const;
+
+ /**
+ * Sets the @p wildcard of the open content.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#oc-wildcard">Wildcard Definition</a>
+ */
+ void setWildcard(const XsdWildcard::Ptr &wildcard);
+
+ /**
+ * Returns the wildcard of the open content.
+ */
+ XsdWildcard::Ptr wildcard() const;
+
+ private:
+ Mode m_mode;
+ XsdWildcard::Ptr m_wildcard;
+ };
+
+ /**
+ * @short Describes the content type of a complex type.
+ */
+ class ContentType : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ContentType> Ptr;
+
+ /**
+ * Describes the variety of the content type.
+ */
+ enum Variety
+ {
+ Empty = 0, ///< The complex type has no further content.
+ Simple, ///< The complex type has only simple type content (e.g. text, number etc.)
+ ElementOnly, ///< The complex type has further elements or attributes but no text as content.
+ Mixed ///< The complex type has further elements or attributes and text as content.
+ };
+
+ /**
+ * Sets the @p variety of the content type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ct-variety">Variety Definition</a>
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the content type.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p particle object of the content type.
+ *
+ * The content type has only a particle object if
+ * its variety is ElementOnly or Mixed.
+ *
+ * @see XsdParticle
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ct-particle">Particle Declaration</a>
+ */
+ void setParticle(const XsdParticle::Ptr &particle);
+
+ /**
+ * Returns the particle object of the content type,
+ * or an empty pointer if its variety is neither
+ * ElementOnly nor Mixed.
+ */
+ XsdParticle::Ptr particle() const;
+
+ /**
+ * Sets the open @p content object of the content type.
+ *
+ * The content type has only an open content object if
+ * its variety is ElementOnly or Mixed.
+ *
+ * @see OpenContent
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ct-open_content">Open Content Declaration</a>
+ */
+ void setOpenContent(const OpenContent::Ptr &content);
+
+ /**
+ * Returns the open content object of the content type,
+ * or an empty pointer if its variety is neither
+ * ElementOnly nor Mixed.
+ */
+ OpenContent::Ptr openContent() const;
+
+ /**
+ * Sets the simple @p type object of the content type.
+ *
+ * The content type has only a simple type object if
+ * its variety is Simple.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ct-simple_type_definition">Simple Type Definition</a>
+ */
+ void setSimpleType(const AnySimpleType::Ptr &type);
+
+ /**
+ * Returns the simple type object of the content type,
+ * or an empty pointer if its variety is not Simple.
+ */
+ AnySimpleType::Ptr simpleType() const;
+
+ private:
+ Variety m_variety;
+ XsdParticle::Ptr m_particle;
+ OpenContent::Ptr m_openContent;
+ XsdSimpleType::Ptr m_simpleType;
+ };
+
+
+ /**
+ * Creates a complex type object with empty content.
+ */
+ XsdComplexType();
+
+ /**
+ * Destroys the complex type object.
+ */
+ ~XsdComplexType() {};
+
+ /**
+ * Returns the display name of the complex type.
+ *
+ * The display name can be used to show the type name
+ * to the user.
+ *
+ * @param namePool The name pool where the type name is stored in.
+ */
+ virtual QString displayName(const NamePool::Ptr &namePool) const;
+
+ /**
+ * Sets the base type of the complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-base_type_definition">Base Type Definition</a>
+ */
+ void setWxsSuperType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the base type of the complex type.
+ */
+ virtual SchemaType::Ptr wxsSuperType() const;
+
+ /**
+ * Sets the context @p component of the complex type.
+ *
+ * The component is either an element declaration or a complex type definition.
+ */
+ void setContext(const NamedSchemaComponent::Ptr &component);
+
+ /**
+ * Returns the context component of the complex type.
+ */
+ NamedSchemaComponent::Ptr context() const;
+
+ /**
+ * Sets the derivation @p method of the complex type.
+ *
+ * The derivation method depends on whether the complex
+ * type object has an extension or restriction object as child.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-derivation_method">Derivation Method Definition</a>
+ * @see DerivationMethod
+ */
+ void setDerivationMethod(DerivationMethod method);
+
+ /**
+ * Returns the derivation method of the complex type.
+ */
+ virtual DerivationMethod derivationMethod() const;
+
+ /**
+ * Sets whether the complex type is @p abstract.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-abstract">Abstract Definition</a>
+ */
+ void setIsAbstract(bool abstract);
+
+ /**
+ * Returns whether the complex type is abstract.
+ */
+ virtual bool isAbstract() const;
+
+ /**
+ * Sets the list of all attribute @p uses of the complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-attribute_uses">Attribute Uses Declaration</a>
+ */
+ void setAttributeUses(const XsdAttributeUse::List &uses);
+
+ /**
+ * Adds a new attribute @p use to the complex type.
+ */
+ void addAttributeUse(const XsdAttributeUse::Ptr &use);
+
+ /**
+ * Returns the list of all attribute uses of the complex type.
+ */
+ XsdAttributeUse::List attributeUses() const;
+
+ /**
+ * Sets the attribute @p wildcard of the complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-attribute_wildcard">Attribute Wildcard Declaration</a>
+ */
+ void setAttributeWildcard(const XsdWildcard::Ptr &wildcard);
+
+ /**
+ * Returns the attribute wildcard of the complex type.
+ */
+ XsdWildcard::Ptr attributeWildcard() const;
+
+ /**
+ * Always returns SchemaType::ComplexType
+ */
+ virtual TypeCategory category() const;
+
+ /**
+ * Sets the content @p type of the complex type.
+ *
+ * @see ContentType
+ */
+ void setContentType(const ContentType::Ptr &type);
+
+ /**
+ * Returns the content type of the complex type.
+ */
+ ContentType::Ptr contentType() const;
+
+ /**
+ * Sets the prohibited @p substitutions of the complex type.
+ *
+ * Only ExtensionConstraint and RestrictionConstraint are allowed.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-prohibited_substitutions">Prohibited Substitutions Definition</a>
+ */
+ void setProhibitedSubstitutions(const BlockingConstraints &substitutions);
+
+ /**
+ * Returns the prohibited substitutions of the complex type.
+ */
+ BlockingConstraints prohibitedSubstitutions() const;
+
+ /**
+ * Sets the @p assertions of the complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-assertions">Assertions Definition</a>
+ */
+ void setAssertions(const XsdAssertion::List &assertions);
+
+ /**
+ * Adds an @p assertion to the complex type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ctd-assertions">Assertions Definition</a>
+ */
+ void addAssertion(const XsdAssertion::Ptr &assertion);
+
+ /**
+ * Returns the assertions of the complex type.
+ */
+ XsdAssertion::List assertions() const;
+
+ /**
+ * Always returns @c true.
+ */
+ virtual bool isDefinedBySchema() const;
+
+ private:
+ SchemaType::Ptr m_superType;
+ NamedSchemaComponent::Ptr m_context;
+ DerivationMethod m_derivationMethod;
+ bool m_isAbstract;
+ XsdAttributeUse::List m_attributeUses;
+ XsdWildcard::Ptr m_attributeWildcard;
+ ContentType::Ptr m_contentType;
+ BlockingConstraints m_prohibitedSubstitutions;
+ XsdAssertion::List m_assertions;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsddocumentation.cpp b/src/xmlpatterns/schema/qxsddocumentation.cpp
new file mode 100644
index 0000000..de610b4
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsddocumentation.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsddocumentation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdDocumentation::XsdDocumentation()
+{
+}
+
+XsdDocumentation::~XsdDocumentation()
+{
+}
+
+void XsdDocumentation::setSource(const AnyURI::Ptr &source)
+{
+ m_source = source;
+}
+
+AnyURI::Ptr XsdDocumentation::source() const
+{
+ return m_source;
+}
+
+void XsdDocumentation::setLanguage(const DerivedString<TypeLanguage>::Ptr &language)
+{
+ m_language = language;
+}
+
+DerivedString<TypeLanguage>::Ptr XsdDocumentation::language() const
+{
+ return m_language;
+}
+
+void XsdDocumentation::setContent(const QString &content)
+{
+ m_content = content;
+}
+
+QString XsdDocumentation::content() const
+{
+ return m_content;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsddocumentation_p.h b/src/xmlpatterns/schema/qxsddocumentation_p.h
new file mode 100644
index 0000000..cdccfd7
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsddocumentation_p.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdDocumentation_H
+#define Patternist_XsdDocumentation_H
+
+#include "qanytype_p.h"
+#include "qanyuri_p.h"
+#include "qderivedstring_p.h"
+#include "qnamedschemacomponent_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD documentation object.
+ *
+ * This class represents the <em>documentation</em> component of an <em>annotation</em> object
+ * of a XML schema as described <a href="http://www.w3.org/TR/xmlschema11-1/#cAnnotations">here</a>.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdDocumentation : public NamedSchemaComponent
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdDocumentation> Ptr;
+ typedef QList<XsdDocumentation::Ptr> List;
+
+ /**
+ * Creates a new documentation object.
+ */
+ XsdDocumentation();
+
+ /**
+ * Destroys the documentation object.
+ */
+ ~XsdDocumentation();
+
+ /**
+ * Sets the @p source of the documentation.
+ *
+ * The source points to an URL that contains more
+ * information.
+ */
+ void setSource(const AnyURI::Ptr &source);
+
+ /**
+ * Returns the source of the documentation.
+ */
+ AnyURI::Ptr source() const;
+
+ /**
+ * Sets the @p language of the documentation.
+ */
+ void setLanguage(const DerivedString<TypeLanguage>::Ptr &language);
+
+ /**
+ * Returns the language of the documentation.
+ */
+ DerivedString<TypeLanguage>::Ptr language() const;
+
+ /**
+ * Sets the @p content of the documentation.
+ *
+ * The content can be of abritrary type.
+ */
+ void setContent(const QString &content);
+
+ /**
+ * Returns the content of the documentation.
+ */
+ QString content() const;
+
+ private:
+ AnyURI::Ptr m_source;
+ DerivedString<TypeLanguage>::Ptr m_language;
+ QString m_content;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdelement.cpp b/src/xmlpatterns/schema/qxsdelement.cpp
new file mode 100644
index 0000000..1ebec06
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdelement.cpp
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdelement_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdElement::Scope::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdElement::Scope::Variety XsdElement::Scope::variety() const
+{
+ return m_variety;
+}
+
+void XsdElement::Scope::setParent(const NamedSchemaComponent::Ptr &parent)
+{
+ m_parent = parent;
+}
+
+NamedSchemaComponent::Ptr XsdElement::Scope::parent() const
+{
+ return m_parent;
+}
+
+void XsdElement::ValueConstraint::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdElement::ValueConstraint::Variety XsdElement::ValueConstraint::variety() const
+{
+ return m_variety;
+}
+
+void XsdElement::ValueConstraint::setValue(const QString &value)
+{
+ m_value = value;
+}
+
+QString XsdElement::ValueConstraint::value() const
+{
+ return m_value;
+}
+
+void XsdElement::ValueConstraint::setLexicalForm(const QString &form)
+{
+ m_lexicalForm = form;
+}
+
+QString XsdElement::ValueConstraint::lexicalForm() const
+{
+ return m_lexicalForm;
+}
+
+void XsdElement::TypeTable::addAlternative(const XsdAlternative::Ptr &alternative)
+{
+ m_alternatives.append(alternative);
+}
+
+XsdAlternative::List XsdElement::TypeTable::alternatives() const
+{
+ return m_alternatives;
+}
+
+void XsdElement::TypeTable::setDefaultTypeDefinition(const XsdAlternative::Ptr &type)
+{
+ m_defaultTypeDefinition = type;
+}
+
+XsdAlternative::Ptr XsdElement::TypeTable::defaultTypeDefinition() const
+{
+ return m_defaultTypeDefinition;
+}
+
+
+XsdElement::XsdElement()
+ : m_isAbstract(false)
+{
+}
+
+bool XsdElement::isElement() const
+{
+ return true;
+}
+
+void XsdElement::setType(const SchemaType::Ptr &type)
+{
+ m_type = type;
+}
+
+SchemaType::Ptr XsdElement::type() const
+{
+ return m_type;
+}
+
+void XsdElement::setScope(const Scope::Ptr &scope)
+{
+ m_scope = scope;
+}
+
+XsdElement::Scope::Ptr XsdElement::scope() const
+{
+ return m_scope;
+}
+
+void XsdElement::setValueConstraint(const ValueConstraint::Ptr &constraint)
+{
+ m_valueConstraint = constraint;
+}
+
+XsdElement::ValueConstraint::Ptr XsdElement::valueConstraint() const
+{
+ return m_valueConstraint;
+}
+
+void XsdElement::setTypeTable(const TypeTable::Ptr &table)
+{
+ m_typeTable = table;
+}
+
+XsdElement::TypeTable::Ptr XsdElement::typeTable() const
+{
+ return m_typeTable;
+}
+
+void XsdElement::setIsAbstract(bool abstract)
+{
+ m_isAbstract = abstract;
+}
+
+bool XsdElement::isAbstract() const
+{
+ return m_isAbstract;
+}
+
+void XsdElement::setIsNillable(bool nillable)
+{
+ m_isNillable = nillable;
+}
+
+bool XsdElement::isNillable() const
+{
+ return m_isNillable;
+}
+
+void XsdElement::setDisallowedSubstitutions(const BlockingConstraints &substitutions)
+{
+ m_disallowedSubstitutions = substitutions;
+}
+
+XsdElement::BlockingConstraints XsdElement::disallowedSubstitutions() const
+{
+ return m_disallowedSubstitutions;
+}
+
+void XsdElement::setSubstitutionGroupExclusions(const SchemaType::DerivationConstraints &exclusions)
+{
+ m_substitutionGroupExclusions = exclusions;
+}
+
+SchemaType::DerivationConstraints XsdElement::substitutionGroupExclusions() const
+{
+ return m_substitutionGroupExclusions;
+}
+
+void XsdElement::setIdentityConstraints(const XsdIdentityConstraint::List &constraints)
+{
+ m_identityConstraints = constraints;
+}
+
+void XsdElement::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint)
+{
+ m_identityConstraints.append(constraint);
+}
+
+XsdIdentityConstraint::List XsdElement::identityConstraints() const
+{
+ return m_identityConstraints;
+}
+
+void XsdElement::setSubstitutionGroupAffiliations(const XsdElement::List &affiliations)
+{
+ m_substitutionGroupAffiliations = affiliations;
+}
+
+XsdElement::List XsdElement::substitutionGroupAffiliations() const
+{
+ return m_substitutionGroupAffiliations;
+}
+
+void XsdElement::addSubstitutionGroup(const XsdElement::Ptr &element)
+{
+ m_substitutionGroups.insert(element);
+}
+
+XsdElement::List XsdElement::substitutionGroups() const
+{
+ return m_substitutionGroups.toList();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdelement_p.h b/src/xmlpatterns/schema/qxsdelement_p.h
new file mode 100644
index 0000000..93c5983
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdelement_p.h
@@ -0,0 +1,403 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdElement_H
+#define Patternist_XsdElement_H
+
+#include "qschemacomponent_p.h"
+#include "qschematype_p.h"
+#include "qxsdalternative_p.h"
+#include "qxsdidentityconstraint_p.h"
+#include "qxsdcomplextype_p.h"
+
+#include <QtCore/QList>
+#include <QtCore/QSet>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD element object.
+ *
+ * This class represents the <em>element</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cElement_Declarations">here</a>.
+ *
+ * It contains information from either a top-level element declaration (as child of a <em>schema</em> object)
+ * or a local element declaration (as descendant of an <em>complexType</em> object).
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSElementDecl">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdElement : public XsdTerm
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdElement> Ptr;
+ typedef QList<XsdElement::Ptr> List;
+
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ed-value_constraint">constraint type</a> of the element.
+ */
+ enum ConstraintType
+ {
+ NoneConstraint, ///< The value of the element has no constraints.
+ DefaultConstraint, ///< The element has a default value set.
+ FixedConstraint ///< The element has a fixed value set.
+ };
+
+ /**
+ * Describes the scope of an element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#sc_e">Scope Definition</a>
+ */
+ class Scope : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<Scope> Ptr;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ad-scope">scope</a> of an attribute.
+ */
+ enum Variety
+ {
+ Global, ///< The element is defined globally as child of the <em>schema</em> object.
+ Local ///< The element is defined locally as child of a complex type or model group definition.
+ };
+
+ /**
+ * Sets the @p variety of the element scope.
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the element scope.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p parent complex type or model group definition of the element scope.
+ */
+ void setParent(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * Returns the parent complex type or model group definition of the element scope.
+ */
+ NamedSchemaComponent::Ptr parent() const;
+
+ private:
+ Variety m_variety;
+ NamedSchemaComponent::Ptr m_parent;
+ };
+
+ /**
+ * Describes a type table of an element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#tt">Type Table Definition</a>
+ */
+ class TypeTable : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<TypeTable> Ptr;
+
+ /**
+ * Adds an @p alternative to the type table.
+ */
+ void addAlternative(const XsdAlternative::Ptr &alternative);
+
+ /**
+ * Returns the alternatives of the type table.
+ */
+ XsdAlternative::List alternatives() const;
+
+ /**
+ * Sets the default @p type definition.
+ */
+ void setDefaultTypeDefinition(const XsdAlternative::Ptr &type);
+
+ /**
+ * Returns the default type definition.
+ */
+ XsdAlternative::Ptr defaultTypeDefinition() const;
+
+ private:
+ XsdAlternative::List m_alternatives;
+ XsdAlternative::Ptr m_defaultTypeDefinition;
+ };
+
+
+ /**
+ * Describes the value constraint of an element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#vc_e">Value Constraint Definition</a>
+ */
+ class ValueConstraint : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ValueConstraint> Ptr;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ed-value_constraint">value constraint</a> of an element.
+ */
+ enum Variety
+ {
+ Default, ///< The element has a default value set.
+ Fixed ///< The element has a fixed value set.
+ };
+
+ /**
+ * Sets the @p variety of the element value constraint.
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the element value constraint.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the @p value of the constraint.
+ */
+ void setValue(const QString &value);
+
+ /**
+ * Returns the value of the constraint.
+ */
+ QString value() const;
+
+ /**
+ * Sets the lexical @p form of the constraint.
+ */
+ void setLexicalForm(const QString &form);
+
+ /**
+ * Returns the lexical form of the constraint.
+ */
+ QString lexicalForm() const;
+
+ private:
+ Variety m_variety;
+ QString m_value;
+ QString m_lexicalForm;
+ };
+
+ /**
+ * Creates a new element object.
+ */
+ XsdElement();
+
+ /**
+ * Always returns @c true, used to avoid dynamic casts.
+ */
+ virtual bool isElement() const;
+
+ /**
+ * Sets the @p type of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-type_definition">Type Definition</a>
+ */
+ void setType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the type of the element.
+ */
+ SchemaType::Ptr type() const;
+
+ /**
+ * Sets the @p scope of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-scope">Scope Definition</a>
+ */
+ void setScope(const Scope::Ptr &scope);
+
+ /**
+ * Returns the scope of the element.
+ */
+ Scope::Ptr scope() const;
+
+ /**
+ * Sets the value @p constraint of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-value_constraint">Value Constraint Definition</a>
+ */
+ void setValueConstraint(const ValueConstraint::Ptr &constraint);
+
+ /**
+ * Returns the value constraint of the element.
+ */
+ ValueConstraint::Ptr valueConstraint() const;
+
+ /**
+ * Sets the type table of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-type_table">Type Table Definition</a>
+ */
+ void setTypeTable(const TypeTable::Ptr &table);
+
+ /**
+ * Returns the type table of the element.
+ */
+ TypeTable::Ptr typeTable() const;
+
+ /**
+ * Sets whether the element is @p abstract.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-abstract">Abstract Definition</a>
+ */
+ void setIsAbstract(bool abstract);
+
+ /**
+ * Returns whether the element is abstract.
+ */
+ bool isAbstract() const;
+
+ /**
+ * Sets whether the element is @p nillable.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-nillable">Nillable Definition</a>
+ */
+ void setIsNillable(bool nillable);
+
+ /**
+ * Returns whether the element is nillable.
+ */
+ bool isNillable() const;
+
+ /**
+ * Sets the disallowed @p substitutions of the element.
+ *
+ * Only ExtensionConstraint, RestrictionConstraint and SubstitutionConstraint are allowed.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-disallowed_substitutions">Disallowed Substitutions Definition</a>
+ */
+ void setDisallowedSubstitutions(const BlockingConstraints &substitutions);
+
+ /**
+ * Returns the disallowed substitutions of the element.
+ */
+ BlockingConstraints disallowedSubstitutions() const;
+
+ /**
+ * Sets the substitution group @p exclusions of the element.
+ *
+ * Only SchemaType::ExtensionConstraint and SchemaType::RestrictionConstraint are allowed.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-substitution_group_exclusions">Substitution Group Exclusions Definition</a>
+ */
+ void setSubstitutionGroupExclusions(const SchemaType::DerivationConstraints &exclusions);
+
+ /**
+ * Returns the substitution group exclusions of the element.
+ */
+ SchemaType::DerivationConstraints substitutionGroupExclusions() const;
+
+ /**
+ * Sets the identity @p constraints of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-identity-constraint_definitions">Identity Constraint Definition</a>
+ */
+ void setIdentityConstraints(const XsdIdentityConstraint::List &constraints);
+
+ /**
+ * Adds a new identity @p constraint to the element.
+ */
+ void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint);
+
+ /**
+ * Returns a list of all identity constraints of the element.
+ */
+ XsdIdentityConstraint::List identityConstraints() const;
+
+ /**
+ * Sets the substitution group @p affiliations of the element.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#ed-substituion_group_affiliations">Substitution Group Affiliations</a>
+ */
+ void setSubstitutionGroupAffiliations(const XsdElement::List &affiliations);
+
+ /**
+ * Returns the substitution group affiliations of the element.
+ */
+ XsdElement::List substitutionGroupAffiliations() const;
+
+ /**
+ * Adds a substitution group to the element.
+ */
+ void addSubstitutionGroup(const XsdElement::Ptr &elements);
+
+ /**
+ * Returns the substitution groups of the element.
+ */
+ XsdElement::List substitutionGroups() const;
+
+ private:
+ SchemaType::Ptr m_type;
+ Scope::Ptr m_scope;
+ ValueConstraint::Ptr m_valueConstraint;
+ TypeTable::Ptr m_typeTable;
+ bool m_isAbstract;
+ bool m_isNillable;
+ BlockingConstraints m_disallowedSubstitutions;
+ SchemaType::DerivationConstraints m_substitutionGroupExclusions;
+ XsdIdentityConstraint::List m_identityConstraints;
+ XsdElement::List m_substitutionGroupAffiliations;
+ QSet<XsdElement::Ptr> m_substitutionGroups;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdfacet.cpp b/src/xmlpatterns/schema/qxsdfacet.cpp
new file mode 100644
index 0000000..80acc74
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdfacet.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdfacet_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdFacet::XsdFacet()
+ : m_type(None)
+{
+}
+
+void XsdFacet::setType(Type type)
+{
+ m_type = type;
+}
+
+XsdFacet::Type XsdFacet::type() const
+{
+ return m_type;
+}
+
+void XsdFacet::setValue(const AtomicValue::Ptr &value)
+{
+ m_value = value;
+}
+
+AtomicValue::Ptr XsdFacet::value() const
+{
+ return m_value;
+}
+
+void XsdFacet::setMultiValue(const AtomicValue::List &value)
+{
+ m_multiValue = value;
+}
+
+AtomicValue::List XsdFacet::multiValue() const
+{
+ return m_multiValue;
+}
+
+void XsdFacet::setAssertions(const XsdAssertion::List &assertions)
+{
+ m_assertions = assertions;
+}
+
+XsdAssertion::List XsdFacet::assertions() const
+{
+ return m_assertions;
+}
+
+void XsdFacet::setFixed(bool fixed)
+{
+ m_fixed = fixed;
+}
+
+bool XsdFacet::fixed() const
+{
+ return m_fixed;
+}
+
+QString XsdFacet::typeName(Type type)
+{
+ switch (type) {
+ case Length: return QLatin1String("length"); break;
+ case MinimumLength: return QLatin1String("minLength"); break;
+ case MaximumLength: return QLatin1String("maxLength"); break;
+ case Pattern: return QLatin1String("pattern"); break;
+ case WhiteSpace: return QLatin1String("whiteSpace"); break;
+ case MaximumInclusive: return QLatin1String("maxInclusive"); break;
+ case MaximumExclusive: return QLatin1String("maxExclusive"); break;
+ case MinimumInclusive: return QLatin1String("minInclusive"); break;
+ case MinimumExclusive: return QLatin1String("minExclusive"); break;
+ case TotalDigits: return QLatin1String("totalDigits"); break;
+ case FractionDigits: return QLatin1String("fractionDigits"); break;
+ case Enumeration: return QLatin1String("enumeration"); break;
+ case Assertion: return QLatin1String("assertion"); break;
+ case None: // fall through
+ default: return QLatin1String("none"); break;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdfacet_p.h b/src/xmlpatterns/schema/qxsdfacet_p.h
new file mode 100644
index 0000000..349e211
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdfacet_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdFacet_H
+#define Patternist_XsdFacet_H
+
+#include "qitem_p.h"
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+#include "qxsdassertion_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD facet object.
+ *
+ * This class represents one of the following XML schema objects:
+ *
+ * <ul>
+ * <li><em>length</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-length">Definition</a></li>
+ * <li><em>minLength</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-minLength">Definition</a></li>
+ * <li><em>maxLength</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-maxLength">Definition</a></li>
+ * <li><em>pattern</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-pattern">Definition</a></li>
+ * <li><em>whiteSpace</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-whiteSpace">Definition</a></li>
+ * <li><em>maxInclusive</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-maxInclusive">Definition</a></li>
+ * <li><em>maxExclusive</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-maxExclusive">Definition</a></li>
+ * <li><em>minInclusive</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-minInclusive">Definition</a></li>
+ * <li><em>minExclusive</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-minExclusive">Definition</a></li>
+ * <li><em>totalDigits</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-totalDigits">Definition</a></li>
+ * <li><em>fractionDigits</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-fractionDigits">Definition</a></li>
+ * <li><em>enumeration</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-enumeration">Definition</a></li>
+ * <li><em>assertion</em> <a href="http://www.w3.org/TR/xmlschema-2/#rf-assertion">Definition</a></li>
+ * </ul>
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSFacet">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdFacet : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdFacet> Ptr;
+
+ /**
+ * Describes the type of the facet.
+ */
+ enum Type
+ {
+ None = 0, ///< An invalid facet.
+ Length = 1 << 0, ///< Match the exact length (<a href="http://www.w3.org/TR/xmlschema-2/#rf-length">Length Definition</a>)
+ MinimumLength = 1 << 1, ///< Match the minimum length (<a href="http://www.w3.org/TR/xmlschema-2/#rf-minLength">Minimum Length Definition</a>)
+ MaximumLength = 1 << 2, ///< Match the maximum length (<a href="http://www.w3.org/TR/xmlschema-2/#rf-maxLength">Maximum Length Definition</a>)
+ Pattern = 1 << 3, ///< Match a regular expression (<a href="http://www.w3.org/TR/xmlschema-2/#rf-pattern">Pattern Definition</a>)
+ WhiteSpace = 1 << 4, ///< Match a whitespace rule (<a href="http://www.w3.org/TR/xmlschema-2/#rf-whiteSpace">White Space Definition</a>)
+ MaximumInclusive = 1 << 5, ///< Match a maximum inclusive (<a href="http://www.w3.org/TR/xmlschema-2/#rf-maxInclusive">Maximum Inclusive Definition</a>)
+ MaximumExclusive = 1 << 6, ///< Match a maximum exclusive (<a href="http://www.w3.org/TR/xmlschema-2/#rf-maxExclusive">Maximum Exclusive Definition</a>)
+ MinimumInclusive = 1 << 7, ///< Match a minimum inclusive (<a href="http://www.w3.org/TR/xmlschema-2/#rf-minInclusive">Minimum Inclusive Definition</a>)
+ MinimumExclusive = 1 << 8, ///< Match a minimum exclusive (<a href="http://www.w3.org/TR/xmlschema-2/#rf-minExclusive">Minimum Exclusive Definition</a>)
+ TotalDigits = 1 << 9, ///< Match some integer digits (<a href="http://www.w3.org/TR/xmlschema-2/#rf-totalDigits">Total Digits Definition</a>)
+ FractionDigits = 1 << 10, ///< Match some double digits (<a href="http://www.w3.org/TR/xmlschema-2/#rf-fractionDigits">Fraction Digits Definition</a>)
+ Enumeration = 1 << 11, ///< Match an enumeration (<a href="http://www.w3.org/TR/xmlschema-2/#rf-enumeration">Enumeration Definition</a>)
+ Assertion = 1 << 12, ///< Match an assertion (<a href="http://www.w3.org/TR/xmlschema-2/#rf-assertion">Assertion Definition</a>)
+ };
+ typedef QHash<XsdFacet::Type, XsdFacet::Ptr> Hash;
+ typedef QHashIterator<XsdFacet::Type, XsdFacet::Ptr> HashIterator;
+
+ /**
+ * Creates a new facet object of type None.
+ */
+ XsdFacet();
+
+ /**
+ * Sets the @p type of the facet.
+ *
+ * @see Type
+ */
+ void setType(Type type);
+
+ /**
+ * Returns the type of the facet.
+ */
+ Type type() const;
+
+ /**
+ * Sets the @p value of the facet.
+ *
+ * Depending on the type of the facet the
+ * value can be a string, interger, double etc.
+ *
+ * @note This method should be used for all types of facets
+ * except Pattern, Enumeration and Assertion.
+ */
+ void setValue(const AtomicValue::Ptr &value);
+
+ /**
+ * Returns the value of the facet or an empty pointer if facet
+ * type is Pattern, Enumeration or Assertion.
+ */
+ AtomicValue::Ptr value() const;
+
+ /**
+ * Sets the @p value of the facet.
+ *
+ * @note This method should be used for if the type of the
+ * facet is Pattern or Enumeration.
+ */
+ void setMultiValue(const AtomicValue::List &value);
+
+ /**
+ * Returns the value of the facet or an empty pointer if facet
+ * type is not of type Pattern or Enumeration.
+ */
+ AtomicValue::List multiValue() const;
+
+ /**
+ * Sets the @p assertions of the facet.
+ *
+ * @note This method should be used if the type of the
+ * facet is Assertion.
+ */
+ void setAssertions(const XsdAssertion::List &assertions);
+
+ /**
+ * Returns the assertions of the facet or an empty pointer if facet
+ * type is not of type Assertion.
+ */
+ XsdAssertion::List assertions() const;
+
+ /**
+ * Sets whether the facet is @p fixed.
+ *
+ * All facets except pattern, enumeration and assertion can be fixed.
+ */
+ void setFixed(bool fixed);
+
+ /**
+ * Returns whether the facet is fixed.
+ */
+ bool fixed() const;
+
+ /**
+ * Returns the textual description of the facet @p type.
+ */
+ static QString typeName(Type type);
+
+ private:
+ Type m_type;
+ AtomicValue::Ptr m_value;
+ AtomicValue::List m_multiValue;
+ XsdAssertion::List m_assertions;
+ bool m_fixed;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdidcache.cpp b/src/xmlpatterns/schema/qxsdidcache.cpp
new file mode 100644
index 0000000..cfca2e9
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidcache.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdidcache_p.h"
+
+#include <QtCore/QReadLocker>
+#include <QtCore/QWriteLocker>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdIdCache::addId(const QString &id)
+{
+ const QWriteLocker locker(&m_lock);
+ Q_ASSERT(!m_ids.contains(id));
+
+ m_ids.insert(id);
+}
+
+bool XsdIdCache::hasId(const QString &id) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_ids.contains(id);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdidcache_p.h b/src/xmlpatterns/schema/qxsdidcache_p.h
new file mode 100644
index 0000000..b24e4b7
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidcache_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdIdCache_H
+#define Patternist_XsdIdCache_H
+
+#include "qschemacomponent_p.h"
+
+#include <QtCore/QExplicitlySharedDataPointer>
+#include <QtCore/QReadWriteLock>
+#include <QtCore/QSet>
+#include <QtCore/QString>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Helper class for keeping track of all existing IDs in a schema.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdIdCache : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdIdCache> Ptr;
+
+ /**
+ * Adds an @p id to the id cache.
+ */
+ void addId(const QString &id);
+
+ /**
+ * Returns whether the id cache contains the given @p id already.
+ */
+ bool hasId(const QString &id) const;
+
+ private:
+ QSet<QString> m_ids;
+ mutable QReadWriteLock m_lock;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdidchelper.cpp b/src/xmlpatterns/schema/qxsdidchelper.cpp
new file mode 100644
index 0000000..7740929
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidchelper.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdidchelper_p.h"
+
+#include "qderivedstring_p.h"
+#include "qxsdschemahelper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+FieldNode::FieldNode()
+{
+}
+
+FieldNode::FieldNode(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type)
+ : m_item(item)
+ , m_data(data)
+ , m_type(type)
+{
+}
+
+bool FieldNode::isEmpty() const
+{
+ return m_item.isNull();
+}
+
+bool FieldNode::isEqualTo(const FieldNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const
+{
+ if (m_type != other.m_type)
+ return false;
+
+ const DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(namePool, m_data);
+ const DerivedString<TypeString>::Ptr otherString = DerivedString<TypeString>::fromLexical(namePool, other.m_data);
+
+ return XsdSchemaHelper::constructAndCompare(string, AtomicComparator::OperatorEqual, otherString, m_type, context, reflection);
+}
+
+QXmlItem FieldNode::item() const
+{
+ return m_item;
+}
+
+TargetNode::TargetNode(const QXmlItem &item)
+ : m_item(item)
+{
+}
+
+QXmlItem TargetNode::item() const
+{
+ return m_item;
+}
+
+QVector<QXmlItem> TargetNode::fieldItems() const
+{
+ QVector<QXmlItem> items;
+
+ for (int i = 0; i < m_fields.count(); ++i)
+ items.append(m_fields.at(i).item());
+
+ return items;
+}
+
+int TargetNode::emptyFieldsCount() const
+{
+ int counter = 0;
+ for (int i = 0; i < m_fields.count(); ++i) {
+ if (m_fields.at(i).isEmpty())
+ ++counter;
+ }
+
+ return counter;
+}
+
+bool TargetNode::fieldsAreEqual(const TargetNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const
+{
+ if (m_fields.count() != other.m_fields.count())
+ return false;
+
+ for (int i = 0; i < m_fields.count(); ++i) {
+ if (!m_fields.at(i).isEqualTo(other.m_fields.at(i), namePool, context, reflection))
+ return false;
+ }
+
+ return true;
+}
+
+void TargetNode::addField(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type)
+{
+ m_fields.append(FieldNode(item, data, type));
+}
+
+bool TargetNode::operator==(const TargetNode &other) const
+{
+ return (m_item.toNodeModelIndex() == other.m_item.toNodeModelIndex());
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdidchelper_p.h b/src/xmlpatterns/schema/qxsdidchelper_p.h
new file mode 100644
index 0000000..f3a9bac
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidchelper_p.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdIdcHelper_H
+#define Patternist_XsdIdcHelper_H
+
+#include "qreportcontext_p.h"
+#include "qschematype_p.h"
+
+#include <QtXmlPatterns/QXmlItem>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short A helper class for validating identity constraints.
+ *
+ * This class represents a field node from the key-sequence as defined in
+ * the validation rules at http://www.w3.org/TR/xmlschema11-1/#d0e32243.
+ */
+ class FieldNode
+ {
+ public:
+ /**
+ * Creates an empty field node.
+ */
+ FieldNode();
+
+ /**
+ * Creates a field node that is bound to a xml node.
+ *
+ * @param item The xml node the field is bound to.
+ * @param data The string content of that field.
+ * @param type The type that is bound to that field.
+ */
+ FieldNode(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type);
+
+ /**
+ * Returns whether this field is empty.
+ *
+ * A field can be empty, if the xpath expression selects an absent attribute
+ * or element.
+ */
+ bool isEmpty() const;
+
+ /**
+ * Returns whether this field is equal to the @p other field.
+ *
+ * Equal means that both have the same type and there content is equal in the
+ * types value space.
+ */
+ bool isEqualTo(const FieldNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const;
+
+ /**
+ * Returns the xml node item the field is bound to.
+ */
+ QXmlItem item() const;
+
+ private:
+ QXmlItem m_item;
+ QString m_data;
+ SchemaType::Ptr m_type;
+ };
+
+ /**
+ * @short A helper class for validating identity constraints.
+ *
+ * This class represents a target or qualified node from the target or qualified
+ * node set as defined in the validation rules at http://www.w3.org/TR/xmlschema11-1/#d0e32243.
+ *
+ * A target node is part of the qualified node set, if all of its fields are not empty.
+ */
+ class TargetNode
+ {
+ public:
+ /**
+ * Defines a set of target nodes.
+ */
+ typedef QSet<TargetNode> Set;
+
+ /**
+ * Creates a new target node that is bound to the xml node @p item.
+ */
+ explicit TargetNode(const QXmlItem &item);
+
+ /**
+ * Returns the xml node item the target node is bound to.
+ */
+ QXmlItem item() const;
+
+ /**
+ * Returns all xml node items, the fields of that target node are bound to.
+ */
+ QVector<QXmlItem> fieldItems() const;
+
+ /**
+ * Returns the number of fields that are empty.
+ */
+ int emptyFieldsCount() const;
+
+ /**
+ * Returns whether the target node has the same fields as the @p other target node.
+ */
+ bool fieldsAreEqual(const TargetNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const;
+
+ /**
+ * Adds a new field to the target node with the given values.
+ */
+ void addField(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type);
+
+ /**
+ * Returns whether the target node is equal to the @p other target node.
+ */
+ bool operator==(const TargetNode &other) const;
+
+ private:
+ QXmlItem m_item;
+ QVector<FieldNode> m_fields;
+ };
+
+ /**
+ * Creates a hash value for the given target @p node.
+ */
+ inline uint qHash(const QPatternist::TargetNode &node)
+ {
+ return qHash(node.item().toNodeModelIndex());
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdidentityconstraint.cpp b/src/xmlpatterns/schema/qxsdidentityconstraint.cpp
new file mode 100644
index 0000000..12f8446
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidentityconstraint.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdidentityconstraint_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdIdentityConstraint::setCategory(Category category)
+{
+ m_category = category;
+}
+
+XsdIdentityConstraint::Category XsdIdentityConstraint::category() const
+{
+ return m_category;
+}
+
+void XsdIdentityConstraint::setSelector(const XsdXPathExpression::Ptr &selector)
+{
+ m_selector = selector;
+}
+
+XsdXPathExpression::Ptr XsdIdentityConstraint::selector() const
+{
+ return m_selector;
+}
+
+void XsdIdentityConstraint::setFields(const XsdXPathExpression::List &fields)
+{
+ m_fields = fields;
+}
+
+void XsdIdentityConstraint::addField(const XsdXPathExpression::Ptr &field)
+{
+ m_fields.append(field);
+}
+
+XsdXPathExpression::List XsdIdentityConstraint::fields() const
+{
+ return m_fields;
+}
+
+void XsdIdentityConstraint::setReferencedKey(const XsdIdentityConstraint::Ptr &referencedKey)
+{
+ m_referencedKey = referencedKey;
+}
+
+XsdIdentityConstraint::Ptr XsdIdentityConstraint::referencedKey() const
+{
+ return m_referencedKey;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdidentityconstraint_p.h b/src/xmlpatterns/schema/qxsdidentityconstraint_p.h
new file mode 100644
index 0000000..a675ea0
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdidentityconstraint_p.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdIdentityConstraint_H
+#define Patternist_XsdIdentityConstraint_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+#include "qxsdxpathexpression_p.h"
+
+#include <QtCore/QStringList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD identity constraint object.
+ *
+ * This class represents the <em>identity constraint</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cIdentity-constraint_Definitions">here</a>.
+ *
+ * It contains information from either a <em>key</em> object, a <em>keyref</em> object or an
+ * <em>unique</em> object.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSIdentityConstraint">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdIdentityConstraint : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdIdentityConstraint> Ptr;
+ typedef QList<XsdIdentityConstraint::Ptr> List;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#icd-identity-constraint_category">category</a> of the identity constraint.
+ */
+ enum Category
+ {
+ Key = 1, ///< The constraint is a key constraint
+ KeyReference, ///< The constraint is a keyref constraint
+ Unique ///< The constraint is an unique constraint
+ };
+
+ /**
+ * Sets the @p category of the identity constraint.
+ *
+ * @see Category
+ */
+ void setCategory(Category category);
+
+ /**
+ * Returns the category of the identity constraint.
+ */
+ Category category() const;
+
+ /**
+ * Sets the @p selector of the identity constraint.
+ *
+ * The selector is a restricted XPath 1.0 expression,
+ * that selects a set of nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#icd-selector"></a>
+ */
+ void setSelector(const XsdXPathExpression::Ptr &selector);
+
+ /**
+ * Returns the selector of the identity constraint.
+ */
+ XsdXPathExpression::Ptr selector() const;
+
+ /**
+ * Sets the @p fields of the identity constraint.
+ *
+ * Each field is a restricted XPath 1.0 expression,
+ * that selects a set of nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#icd-fields"></a>
+ */
+ void setFields(const XsdXPathExpression::List &fields);
+
+ /**
+ * Adds a new @p field to the identity constraint.
+ */
+ void addField(const XsdXPathExpression::Ptr &field);
+
+ /**
+ * Returns all fields of the identity constraint.
+ */
+ XsdXPathExpression::List fields() const;
+
+ /**
+ * Sets the referenced @p key of the identity constraint.
+ *
+ * The key points to a identity constraint of type Key or Unique.
+ *
+ * The identity constraint has only a referenced key if its
+ * type is KeyReference.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#icd-referenced_key"></a>
+ */
+ void setReferencedKey(const XsdIdentityConstraint::Ptr &key);
+
+ /**
+ * Returns the referenced key of the identity constraint or an empty
+ * pointer if its type is not KeyReference.
+ */
+ XsdIdentityConstraint::Ptr referencedKey() const;
+
+ private:
+ Category m_category;
+ XsdXPathExpression::Ptr m_selector;
+ XsdXPathExpression::List m_fields;
+ XsdIdentityConstraint::Ptr m_referencedKey;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdinstancereader.cpp b/src/xmlpatterns/schema/qxsdinstancereader.cpp
new file mode 100644
index 0000000..a7cb735
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdinstancereader.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdinstancereader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdInstanceReader::XsdInstanceReader(const QAbstractXmlNodeModel *model, const XsdSchemaContext::Ptr &context)
+ : m_context(context)
+ , m_model(model->iterate(model->root(QXmlNodeModelIndex()), QXmlNodeModelIndex::AxisChild))
+{
+}
+
+bool XsdInstanceReader::atEnd() const
+{
+ return (m_model.current() == AbstractXmlPullProvider::EndOfInput);
+}
+
+void XsdInstanceReader::readNext()
+{
+ m_model.next();
+
+ if (m_model.current() == AbstractXmlPullProvider::StartElement) {
+ m_cachedAttributes = m_model.attributes();
+ m_cachedAttributeItems = m_model.attributeItems();
+ m_cachedSourceLocation = m_model.sourceLocation();
+ m_cachedItem = QXmlItem(m_model.index());
+ }
+}
+
+bool XsdInstanceReader::isStartElement() const
+{
+ return (m_model.current() == AbstractXmlPullProvider::StartElement);
+}
+
+bool XsdInstanceReader::isEndElement() const
+{
+ return (m_model.current() == AbstractXmlPullProvider::EndElement);
+}
+
+bool XsdInstanceReader::hasChildText() const
+{
+ const QXmlNodeModelIndex index = m_model.index();
+ QXmlNodeModelIndex::Iterator::Ptr it = index.model()->iterate(index, QXmlNodeModelIndex::AxisChild);
+
+ QXmlNodeModelIndex currentIndex = it->next();
+ while (!currentIndex.isNull()) {
+ if (currentIndex.kind() == QXmlNodeModelIndex::Text)
+ return true;
+
+ currentIndex = it->next();
+ }
+
+ return false;
+}
+
+bool XsdInstanceReader::hasChildElement() const
+{
+ const QXmlNodeModelIndex index = m_model.index();
+ QXmlNodeModelIndex::Iterator::Ptr it = index.model()->iterate(index, QXmlNodeModelIndex::AxisChild);
+
+ QXmlNodeModelIndex currentIndex = it->next();
+ while (!currentIndex.isNull()) {
+ if (currentIndex.kind() == QXmlNodeModelIndex::Element)
+ return true;
+
+ currentIndex = it->next();
+ }
+
+ return false;
+}
+
+QXmlName XsdInstanceReader::name() const
+{
+ return m_model.name();
+}
+
+QXmlName XsdInstanceReader::convertToQName(const QString &name) const
+{
+ const int pos = name.indexOf(QLatin1Char(':'));
+
+ QXmlName::PrefixCode prefixCode = 0;
+ QXmlName::NamespaceCode namespaceCode;
+ QXmlName::LocalNameCode localNameCode;
+ if (pos != -1) {
+ prefixCode = m_context->namePool()->allocatePrefix(name.left(pos));
+ namespaceCode = m_cachedItem.toNodeModelIndex().namespaceForPrefix(prefixCode);
+ localNameCode = m_context->namePool()->allocateLocalName(name.mid(pos + 1));
+ } else {
+ prefixCode = StandardPrefixes::empty;
+ namespaceCode = m_cachedItem.toNodeModelIndex().namespaceForPrefix(prefixCode);
+ if (namespaceCode == -1)
+ namespaceCode = StandardNamespaces::empty;
+ localNameCode = m_context->namePool()->allocateLocalName(name);
+ }
+
+ return QXmlName(namespaceCode, localNameCode, prefixCode);
+}
+
+bool XsdInstanceReader::hasAttribute(const QXmlName &name) const
+{
+ return m_cachedAttributes.contains(name);
+}
+
+QString XsdInstanceReader::attribute(const QXmlName &name) const
+{
+ Q_ASSERT(m_cachedAttributes.contains(name));
+
+ return m_cachedAttributes.value(name);
+}
+
+QSet<QXmlName> XsdInstanceReader::attributeNames() const
+{
+ return m_cachedAttributes.keys().toSet();
+}
+
+QString XsdInstanceReader::text() const
+{
+ const QXmlNodeModelIndex index = m_model.index();
+ QXmlNodeModelIndex::Iterator::Ptr it = index.model()->iterate(index, QXmlNodeModelIndex::AxisChild);
+
+ QString result;
+
+ QXmlNodeModelIndex currentIndex = it->next();
+ while (!currentIndex.isNull()) {
+ if (currentIndex.kind() == QXmlNodeModelIndex::Text) {
+ result.append(Item(currentIndex).stringValue());
+ }
+
+ currentIndex = it->next();
+ }
+
+ return result;
+}
+
+QXmlItem XsdInstanceReader::item() const
+{
+ return m_cachedItem;
+}
+
+QXmlItem XsdInstanceReader::attributeItem(const QXmlName &name) const
+{
+ return m_cachedAttributeItems.value(name);
+}
+
+QSourceLocation XsdInstanceReader::sourceLocation() const
+{
+ return m_cachedSourceLocation;
+}
+
+QVector<QXmlName> XsdInstanceReader::namespaceBindings(const QXmlNodeModelIndex &index) const
+{
+ return index.namespaceBindings();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdinstancereader_p.h b/src/xmlpatterns/schema/qxsdinstancereader_p.h
new file mode 100644
index 0000000..9c9fcd1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdinstancereader_p.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdInstanceReader_H
+#define Patternist_XsdInstanceReader_H
+
+#include "qabstractxmlnodemodel.h"
+#include "qpullbridge_p.h"
+#include "qxsdschemacontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short The schema instance reader.
+ *
+ * This class reads in a xml instance document from a QAbstractXmlNodeModel
+ * and provides a QXmlStreamReader like interface with some additional context
+ * information.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdInstanceReader
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdInstanceReader> Ptr;
+
+ /**
+ * Creates a new instance reader that will read the data from
+ * the given @p model.
+ *
+ * @param model The model the data are read from.
+ * @param context The context that is used for error reporting etc.
+ */
+ XsdInstanceReader(const QAbstractXmlNodeModel *model, const XsdSchemaContext::Ptr &context);
+
+ protected:
+ /**
+ * Returns @c true if the end of the document is reached, @c false otherwise.
+ */
+ bool atEnd() const;
+
+ /**
+ * Reads the next node from the document.
+ */
+ void readNext();
+
+ /**
+ * Returns whether the current node is a start element.
+ */
+ bool isStartElement() const;
+
+ /**
+ * Returns whether the current node is an end element.
+ */
+ bool isEndElement() const;
+
+ /**
+ * Returns whether the current node has a text node among its children.
+ */
+ bool hasChildText() const;
+
+ /**
+ * Returns whether the current node has an element node among its children.
+ */
+ bool hasChildElement() const;
+
+ /**
+ * Returns the name of the current node.
+ */
+ QXmlName name() const;
+
+ /**
+ * Returns whether the current node has an attribute with the given @p name.
+ */
+ bool hasAttribute(const QXmlName &name) const;
+
+ /**
+ * Returns the attribute with the given @p name of the current node.
+ */
+ QString attribute(const QXmlName &name) const;
+
+ /**
+ * Returns the list of attribute names of the current node.
+ */
+ QSet<QXmlName> attributeNames() const;
+
+ /**
+ * Returns the concatenated text of all direct child text nodes.
+ */
+ QString text() const;
+
+ /**
+ * Converts a qualified name into a QXmlName according to the namespace
+ * mappings of the current node.
+ */
+ QXmlName convertToQName(const QString &name) const;
+
+ /**
+ * Returns a source location object for the current position.
+ */
+ QSourceLocation sourceLocation() const;
+
+ /**
+ * Returns the QXmlItem for the current position.
+ */
+ QXmlItem item() const;
+
+ /**
+ * Returns the QXmlItem for the attribute with the given @p name at the current position.
+ */
+ QXmlItem attributeItem(const QXmlName &name) const;
+
+ /**
+ * Returns the namespace bindings for the given node model @p index.
+ */
+ QVector<QXmlName> namespaceBindings(const QXmlNodeModelIndex &index) const;
+
+ /**
+ * The shared schema context.
+ */
+ XsdSchemaContext::Ptr m_context;
+
+ private:
+ PullBridge m_model;
+ QHash<QXmlName, QString> m_cachedAttributes;
+ QHash<QXmlName, QXmlItem> m_cachedAttributeItems;
+ QSourceLocation m_cachedSourceLocation;
+ QXmlItem m_cachedItem;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdmodelgroup.cpp b/src/xmlpatterns/schema/qxsdmodelgroup.cpp
new file mode 100644
index 0000000..69e5fad
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdmodelgroup.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdmodelgroup_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdModelGroup::XsdModelGroup()
+ : m_compositor(SequenceCompositor)
+{
+}
+
+bool XsdModelGroup::isModelGroup() const
+{
+ return true;
+}
+
+void XsdModelGroup::setCompositor(ModelCompositor compositor)
+{
+ m_compositor = compositor;
+}
+
+XsdModelGroup::ModelCompositor XsdModelGroup::compositor() const
+{
+ return m_compositor;
+}
+
+void XsdModelGroup::setParticles(const XsdParticle::List &particles)
+{
+ m_particles = particles;
+}
+
+XsdParticle::List XsdModelGroup::particles() const
+{
+ return m_particles;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdmodelgroup_p.h b/src/xmlpatterns/schema/qxsdmodelgroup_p.h
new file mode 100644
index 0000000..c4f54e5
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdmodelgroup_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdModelGroup_H
+#define Patternist_XsdModelGroup_H
+
+#include "qxsdparticle_p.h"
+#include "qxsdterm_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename N> class QList;
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD model group object.
+ *
+ * This class represents the <em>model group</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cModel_Group_Definitions">here</a>.
+ *
+ * It contains information from either a <em>sequence</em> object, a <em>choice</em> object or an
+ * <em>all</em> object.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSModelGroup">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdModelGroup : public XsdTerm
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdModelGroup> Ptr;
+ typedef QList<XsdModelGroup::Ptr> List;
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#mg-compositor">compositor</a> of the model group.
+ */
+ enum ModelCompositor
+ {
+ SequenceCompositor, ///< The model group is a sequence.
+ ChoiceCompositor, ///< The model group is a choice.
+ AllCompositor ///< The model group contains elements only.
+ };
+
+ /**
+ * Creates a new model group object.
+ */
+ XsdModelGroup();
+
+ /**
+ * Returns always @c true, used to avoid dynamic casts.
+ */
+ virtual bool isModelGroup() const;
+
+ /**
+ * Sets the @p compositor of the model group.
+ *
+ * @see ModelCompositor
+ */
+ void setCompositor(ModelCompositor compositor);
+
+ /**
+ * Returns the compositor of the model group.
+ */
+ ModelCompositor compositor() const;
+
+ /**
+ * Sets the list of @p particles of the model group.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#mg-particles">Particles Definition</a>
+ */
+ void setParticles(const XsdParticle::List &particles);
+
+ /**
+ * Returns the list of particles of the model group.
+ */
+ XsdParticle::List particles() const;
+
+ private:
+ ModelCompositor m_compositor;
+ XsdParticle::List m_particles;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdnotation.cpp b/src/xmlpatterns/schema/qxsdnotation.cpp
new file mode 100644
index 0000000..2cd27a4
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdnotation.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdnotation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdNotation::setPublicId(const DerivedString<TypeToken>::Ptr &id)
+{
+ m_publicId = id;
+}
+
+DerivedString<TypeToken>::Ptr XsdNotation::publicId() const
+{
+ return m_publicId;
+}
+
+void XsdNotation::setSystemId(const AnyURI::Ptr &id)
+{
+ m_systemId = id;
+}
+
+AnyURI::Ptr XsdNotation::systemId() const
+{
+ return m_systemId;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdnotation_p.h b/src/xmlpatterns/schema/qxsdnotation_p.h
new file mode 100644
index 0000000..598392a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdnotation_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdNotation_H
+#define Patternist_XsdNotation_H
+
+#include "qanyuri_p.h"
+#include "qderivedstring_p.h"
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD notation object, which should not
+ * be confused with the atomic type @c xs:NOTATION.
+ *
+ * This class represents the <em>notation</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cNotation_Declarations">here</a>.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#XS-NotationDecl">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdNotation : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdNotation> Ptr;
+ typedef QList<XsdNotation::Ptr> List;
+
+ /**
+ * Sets the public @p identifier of the notation.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#nd-public_identifier">Public Identifier Definition</a>
+ */
+ void setPublicId(const DerivedString<TypeToken>::Ptr &identifier);
+
+ /**
+ * Returns the public identifier of the notation.
+ */
+ DerivedString<TypeToken>::Ptr publicId() const;
+
+ /**
+ * Sets the system @p identifier of the notation.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#nd-system_identifier">System Identifier Definition</a>
+ */
+ void setSystemId(const AnyURI::Ptr &identifier);
+
+ /**
+ * Returns the system identifier of the notation.
+ */
+ AnyURI::Ptr systemId() const;
+
+ private:
+ DerivedString<TypeToken>::Ptr m_publicId;
+ AnyURI::Ptr m_systemId;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdparticle.cpp b/src/xmlpatterns/schema/qxsdparticle.cpp
new file mode 100644
index 0000000..650524c
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdparticle.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdparticle_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdParticle::XsdParticle()
+ : m_minimumOccurs(1)
+ , m_maximumOccurs(1)
+ , m_maximumOccursUnbounded(false)
+{
+}
+
+void XsdParticle::setMinimumOccurs(unsigned int occurs)
+{
+ m_minimumOccurs = occurs;
+}
+
+unsigned int XsdParticle::minimumOccurs() const
+{
+ return m_minimumOccurs;
+}
+
+void XsdParticle::setMaximumOccurs(unsigned int occurs)
+{
+ m_maximumOccurs = occurs;
+}
+
+unsigned int XsdParticle::maximumOccurs() const
+{
+ return m_maximumOccurs;
+}
+
+void XsdParticle::setMaximumOccursUnbounded(bool unbounded)
+{
+ m_maximumOccursUnbounded = unbounded;
+}
+
+bool XsdParticle::maximumOccursUnbounded() const
+{
+ return m_maximumOccursUnbounded;
+}
+
+void XsdParticle::setTerm(const XsdTerm::Ptr &term)
+{
+ m_term = term;
+}
+
+XsdTerm::Ptr XsdParticle::term() const
+{
+ return m_term;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdparticle_p.h b/src/xmlpatterns/schema/qxsdparticle_p.h
new file mode 100644
index 0000000..4e6561e
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdparticle_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdParticle_H
+#define Patternist_XsdParticle_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qxsdterm_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD particle object.
+ *
+ * This class represents the <em>particle</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#cParticles">here</a>.
+ *
+ * It contains information about the number of occurrence and a reference to
+ * either an <em>element</em> object, a <em>group</em> object or an <em>any</em> object.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSParticle">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdParticle : public NamedSchemaComponent
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdParticle> Ptr;
+ typedef QList<XsdParticle::Ptr> List;
+
+ /**
+ * Creates a new particle object.
+ */
+ XsdParticle();
+
+ /**
+ * Sets the minimum @p occurrence of the particle.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#p-min_occurs">Minimum Occurrence Definition</a>
+ */
+ void setMinimumOccurs(unsigned int occurrence);
+
+ /**
+ * Returns the minimum occurrence of the particle.
+ */
+ unsigned int minimumOccurs() const;
+
+ /**
+ * Sets the maximum @p occurrence of the particle.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#p-max_occurs">Maximum Occurrence Definition</a>
+ */
+ void setMaximumOccurs(unsigned int occurrence);
+
+ /**
+ * Returns the maximum occurrence of the particle.
+ *
+ * @note This value has only a meaning if maximumOccursUnbounded is @c false.
+ */
+ unsigned int maximumOccurs() const;
+
+ /**
+ * Sets whether the maximum occurrence of the particle is unbounded.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#p-max_occurs">Maximum Occurrence Definition</a>
+ */
+ void setMaximumOccursUnbounded(bool unbounded);
+
+ /**
+ * Returns whether the maximum occurrence of the particle is unbounded.
+ */
+ bool maximumOccursUnbounded() const;
+
+ /**
+ * Sets the @p term of the particle.
+ *
+ * The term can be an element, a model group or an element wildcard.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#p-term">Term Definition</a>
+ */
+ void setTerm(const XsdTerm::Ptr &term);
+
+ /**
+ * Returns the term of the particle.
+ */
+ XsdTerm::Ptr term() const;
+
+ private:
+ unsigned int m_minimumOccurs;
+ unsigned int m_maximumOccurs;
+ bool m_maximumOccursUnbounded;
+ XsdTerm::Ptr m_term;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp
new file mode 100644
index 0000000..15c2afe
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp
@@ -0,0 +1,570 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdparticlechecker_p.h"
+
+#include "qxsdelement_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdschemahelper_p.h"
+#include "qxsdstatemachine_p.h"
+#include "qxsdstatemachinebuilder_p.h"
+#include "qxsdtypechecker_p.h"
+
+#include <QtCore/QFile>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+ /**
+ * This template specialization is picked up by XsdStateMachine and allows us
+ * to print nice edge labels.
+ */
+ template <>
+ QString XsdStateMachine<XsdTerm::Ptr>::transitionTypeToString(XsdTerm::Ptr term) const
+ {
+ if (!term)
+ return QLatin1String("(empty)");
+
+ if (term->isElement()) {
+ return XsdElement::Ptr(term)->displayName(m_namePool);
+ } else if (term->isWildcard()) {
+ const XsdWildcard::Ptr wildcard(term);
+ return QLatin1String("(wildcard)");
+ } else {
+ return QString();
+ }
+ }
+}
+
+/**
+ * This method is used by the isUPAConform method to check whether @p term and @p otherTerm
+ * are the same resp. match each other.
+ */
+static bool termMatches(const XsdTerm::Ptr &term, const XsdTerm::Ptr &otherTerm, const NamePool::Ptr &namePool)
+{
+ if (term->isElement()) {
+ const XsdElement::Ptr element(term);
+
+ if (otherTerm->isElement()) {
+ // both, the term and the other term are elements
+
+ const XsdElement::Ptr otherElement(otherTerm);
+
+ // if they have the same name they match
+ if (element->name(namePool) == otherElement->name(namePool))
+ return true;
+
+ } else if (otherTerm->isWildcard()) {
+ // the term is an element and the other term a wildcard
+
+ const XsdWildcard::Ptr wildcard(otherTerm);
+
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ QXmlName name = element->name(namePool);
+ if (name.namespaceURI() == StandardNamespaces::empty)
+ name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+
+ // if the wildcards namespace constraint allows the elements name, they match
+ if (XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool))
+ return true;
+ }
+ } else if (term->isWildcard()) {
+ const XsdWildcard::Ptr wildcard(term);
+
+ if (otherTerm->isElement()) {
+ // the term is a wildcard and the other term an element
+
+ const XsdElement::Ptr otherElement(otherTerm);
+
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ QXmlName name = otherElement->name(namePool);
+ if (name.namespaceURI() == StandardNamespaces::empty)
+ name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+
+ // if the wildcards namespace constraint allows the elements name, they match
+ if (XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool))
+ return true;
+
+ } else if (otherTerm->isWildcard()) {
+ // both, the term and the other term are wildcards
+
+ const XsdWildcard::Ptr otherWildcard(otherTerm);
+
+ // check if the range of the wildcard overlaps.
+ const XsdWildcard::Ptr intersectionWildcard = XsdSchemaHelper::wildcardIntersection(wildcard, otherWildcard);
+ if (!intersectionWildcard ||
+ (intersectionWildcard && !(intersectionWildcard->namespaceConstraint()->variety() != XsdWildcard::NamespaceConstraint::Not && intersectionWildcard->namespaceConstraint()->namespaces().isEmpty())))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * This method is used by the subsumes algorithm to check whether the @p derivedTerm is validly derived from the @p baseTerm.
+ *
+ * @param baseTerm The term of the base component (type or group).
+ * @param derivedTerm The term of the derived component (type or group).
+ * @param particles A hash to map the passed base and derived term to the particles they belong to.
+ * @param context The schema context.
+ * @param errorMsg The error message in the case that an error occurs.
+ */
+static bool derivedTermValid(const XsdTerm::Ptr &baseTerm, const XsdTerm::Ptr &derivedTerm, const QHash<XsdTerm::Ptr, XsdParticle::Ptr> &particles, const XsdSchemaContext::Ptr &context, QString &errorMsg)
+{
+ const NamePool::Ptr namePool(context->namePool());
+
+ // find the particles where the base and derived term belongs to
+ const XsdParticle::Ptr baseParticle = particles.value(baseTerm);
+ const XsdParticle::Ptr derivedParticle = particles.value(derivedTerm);
+
+ // check that an empty particle can not be derived from a non-empty particle
+ if (derivedParticle && baseParticle) {
+ if (XsdSchemaHelper::isParticleEmptiable(derivedParticle) && !XsdSchemaHelper::isParticleEmptiable(baseParticle)) {
+ errorMsg = QtXmlPatterns::tr("Empty particle cannot be derived from non-empty particle.");
+ return false;
+ }
+ }
+
+ if (baseTerm->isElement()) {
+ const XsdElement::Ptr element(baseTerm);
+
+ if (derivedTerm->isElement()) {
+ // if both terms are elements
+
+ const XsdElement::Ptr derivedElement(derivedTerm);
+
+ // check names are equal
+ if (element->name(namePool) != derivedElement->name(namePool)) {
+ errorMsg = QtXmlPatterns::tr("Derived particle is missing element %1.").arg(formatKeyword(element->displayName(namePool)));
+ return false;
+ }
+
+ // check value constraints are equal (if available)
+ if (element->valueConstraint() && element->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
+ if (!derivedElement->valueConstraint()) {
+ errorMsg = QtXmlPatterns::tr("Derived element %1 is missing value constraint as defined in base particle.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+
+ if (derivedElement->valueConstraint()->variety() != XsdElement::ValueConstraint::Fixed) {
+ errorMsg = QtXmlPatterns::tr("Derived element %1 has weaker value constraint than base particle.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+
+ const QSourceLocation dummyLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1);
+ const XsdTypeChecker checker(context, QVector<QXmlName>(), dummyLocation);
+ if (!checker.valuesAreEqual(element->valueConstraint()->value(), derivedElement->valueConstraint()->value(), derivedElement->type())) {
+ errorMsg = QtXmlPatterns::tr("Fixed value constraint of element %1 differs from value constraint in base particle.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+ }
+
+ // check that a derived element can not be nillable if the base element is not nillable
+ if (!element->isNillable() && derivedElement->isNillable()) {
+ errorMsg = QtXmlPatterns::tr("Derived element %1 cannot be nillable as base element is not nillable.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+
+ // check that the constraints of the derived element are more strict then the constraints of the base element
+ const XsdElement::BlockingConstraints baseConstraints = element->disallowedSubstitutions();
+ const XsdElement::BlockingConstraints derivedConstraints = derivedElement->disallowedSubstitutions();
+ if (((baseConstraints & XsdElement::RestrictionConstraint) && !(derivedConstraints & XsdElement::RestrictionConstraint)) ||
+ ((baseConstraints & XsdElement::ExtensionConstraint) && !(derivedConstraints & XsdElement::ExtensionConstraint)) ||
+ ((baseConstraints & XsdElement::SubstitutionConstraint) && !(derivedConstraints & XsdElement::SubstitutionConstraint))) {
+ errorMsg = QtXmlPatterns::tr("Block constraints of derived element %1 must not be more weaker than in the base element.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+
+ // if the type of both elements is the same we can stop testing here
+ if (element->type()->name(namePool) == derivedElement->type()->name(namePool))
+ return true;
+
+ // check that the type of the derived element can validly derived from the type of the base element
+ if (derivedElement->type()->isSimpleType()) {
+ if (!XsdSchemaHelper::isSimpleDerivationOk(derivedElement->type(), element->type(), SchemaType::DerivationConstraints())) {
+ errorMsg = QtXmlPatterns::tr("Simple type of derived element %1 cannot be validly derived from base element.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+ } else if (derivedElement->type()->isComplexType()) {
+ if (!XsdSchemaHelper::isComplexDerivationOk(derivedElement->type(), element->type(), SchemaType::DerivationConstraints())) {
+ errorMsg = QtXmlPatterns::tr("Complex type of derived element %1 cannot be validly derived from base element.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+ }
+
+ // if both, derived and base element, have a complex type that contains a particle itself, apply the subsumes algorithm
+ // recursive on their particles
+ if (element->type()->isComplexType() && derivedElement->type()->isComplexType()) {
+ if (element->type()->isDefinedBySchema() && derivedElement->type()->isDefinedBySchema()) {
+ const XsdComplexType::Ptr baseType(element->type());
+ const XsdComplexType::Ptr derivedType(derivedElement->type());
+ if ((baseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly ||
+ baseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) &&
+ (derivedType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly ||
+ derivedType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {
+
+ return XsdParticleChecker::subsumes(baseType->contentType()->particle(), derivedType->contentType()->particle(), context, errorMsg);
+ }
+ }
+ }
+
+ return true;
+ } else if (derivedTerm->isWildcard()) {
+ // derive a wildcard from an element is not allowed
+ errorMsg = QtXmlPatterns::tr("Element %1 is missing in derived particle.").arg(formatKeyword(element->displayName(namePool)));
+ return false;
+ }
+ } else if (baseTerm->isWildcard()) {
+ const XsdWildcard::Ptr wildcard(baseTerm);
+
+ if (derivedTerm->isElement()) {
+ // the base term is a wildcard and derived term an element
+
+ const XsdElement::Ptr derivedElement(derivedTerm);
+
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ QXmlName name = derivedElement->name(namePool);
+ if (name.namespaceURI() == StandardNamespaces::empty)
+ name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+
+ // check that name of the element is allowed by the wildcards namespace constraint
+ if (!XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool)) {
+ errorMsg = QtXmlPatterns::tr("Element %1 does not match namespace constraint of wildcard in base particle.").arg(formatKeyword(derivedElement->displayName(namePool)));
+ return false;
+ }
+
+ } else if (derivedTerm->isWildcard()) {
+ // both, derived and base term are wildcards
+
+ const XsdWildcard::Ptr derivedWildcard(derivedTerm);
+
+ // check that the derived wildcard is a valid subset of the base wildcard
+ if (!XsdSchemaHelper::isWildcardSubset(derivedWildcard, wildcard)) {
+ errorMsg = QtXmlPatterns::tr("Wildcard in derived particle is not a valid subset of wildcard in base particle.");
+ return false;
+ }
+
+ if (!XsdSchemaHelper::checkWildcardProcessContents(wildcard, derivedWildcard)) {
+ errorMsg = QtXmlPatterns::tr("processContent of wildcard in derived particle is weaker than wildcard in base particle.");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+typedef QHash<QXmlName, XsdElement::Ptr> ElementHash;
+
+/**
+ * Internal helper method that checks if the given @p particle contains an element with the
+ * same name and type twice.
+ */
+static bool hasDuplicatedElementsInternal(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, ElementHash &hash, XsdElement::Ptr &conflictingElement)
+{
+ const XsdTerm::Ptr term = particle->term();
+ if (term->isElement()) {
+ const XsdElement::Ptr mainElement(term);
+ XsdElement::List substGroups = mainElement->substitutionGroups();
+ if (substGroups.isEmpty())
+ substGroups << mainElement;
+
+ for (int i = 0; i < substGroups.count(); ++i) {
+ const XsdElement::Ptr element = substGroups.at(i);
+ if (hash.contains(element->name(namePool))) {
+ if (element->type()->name(namePool) != hash.value(element->name(namePool))->type()->name(namePool)) {
+ conflictingElement = element;
+ return true;
+ }
+ } else {
+ hash.insert(element->name(namePool), element);
+ }
+ }
+ } else if (term->isModelGroup()) {
+ const XsdModelGroup::Ptr group(term);
+ const XsdParticle::List particles = group->particles();
+ for (int i = 0; i < particles.count(); ++i) {
+ if (hasDuplicatedElementsInternal(particles.at(i), namePool, hash, conflictingElement))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool XsdParticleChecker::hasDuplicatedElements(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, XsdElement::Ptr &conflictingElement)
+{
+ ElementHash hash;
+ return hasDuplicatedElementsInternal(particle, namePool, hash, conflictingElement);
+}
+
+bool XsdParticleChecker::isUPAConform(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool)
+{
+
+ /**
+ * In case we encounter an <xsd:all> element, don't construct a state machine, but use the approach
+ * described at http://www.w3.org/TR/xmlschema-1/#non-ambig
+ * Reason: For n elements inside the <xsd:all>, represented in the NDA, the state machine
+ * constructs n! states in the DFA, which does not scale.
+ */
+ if (particle->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr group(particle->term());
+ if (group->compositor() == XsdModelGroup::AllCompositor)
+ return isUPAConformXsdAll(particle, namePool);
+ }
+
+ /**
+ * The algorithm is implemented like described in http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html#S2.2
+ */
+
+ // create a state machine for the given particle
+ XsdStateMachine<XsdTerm::Ptr> stateMachine(namePool);
+
+ XsdStateMachineBuilder builder(&stateMachine, namePool);
+ const XsdStateMachine<XsdTerm::Ptr>::StateId endState = builder.reset();
+ const XsdStateMachine<XsdTerm::Ptr>::StateId startState = builder.buildParticle(particle, endState);
+ builder.addStartState(startState);
+
+/*
+ static int counter = 0;
+ {
+ QFile file(QString("/tmp/file_upa%1.dot").arg(counter));
+ file.open(QIODevice::WriteOnly);
+ stateMachine.outputGraph(&file, "Base");
+ file.close();
+ }
+ ::system(QString("dot -Tpng /tmp/file_upa%1.dot -o/tmp/file_upa%1.png").arg(counter).toLatin1().data());
+*/
+ const XsdStateMachine<XsdTerm::Ptr> dfa = stateMachine.toDFA();
+/*
+ {
+ QFile file(QString("/tmp/file_upa%1dfa.dot").arg(counter));
+ file.open(QIODevice::WriteOnly);
+ dfa.outputGraph(&file, "Base");
+ file.close();
+ }
+ ::system(QString("dot -Tpng /tmp/file_upa%1dfa.dot -o/tmp/file_upa%1dfa.png").arg(counter).toLatin1().data());
+*/
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateType> states = dfa.states();
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > > transitions = dfa.transitions();
+
+ // the basic idea of that algorithm is to iterate over all states of that machine and check that no two edges
+ // that match on the same term leave a state, so for a given term it should always be obvious which edge to take
+ QHashIterator<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateType> stateIt(states);
+ while (stateIt.hasNext()) { // iterate over all states
+ stateIt.next();
+
+ // fetch all transitions the current state allows
+ const QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > currentTransitions = transitions.value(stateIt.key());
+ QHashIterator<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > transitionIt(currentTransitions);
+ while (transitionIt.hasNext()) { // iterate over all transitions
+ transitionIt.next();
+
+ if (transitionIt.value().size() > 1) {
+ // we have one state with two edges leaving it, that means
+ // the XsdTerm::Ptr exists twice, that is an error
+ return false;
+ }
+
+ QHashIterator<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > innerTransitionIt(currentTransitions);
+ while (innerTransitionIt.hasNext()) { // iterate over all transitions again, as we have to compare all transitions with all
+ innerTransitionIt.next();
+
+ if (transitionIt.key() == innerTransitionIt.key()) // do no compare with ourself
+ continue;
+
+ // use the helper method termMatches to check if both term matches
+ if (termMatches(transitionIt.key(), innerTransitionIt.key(), namePool))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool XsdParticleChecker::isUPAConformXsdAll(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool)
+{
+ /**
+ * see http://www.w3.org/TR/xmlschema-1/#non-ambig
+ */
+ const XsdModelGroup::Ptr group(particle->term());
+ const XsdParticle::List particles = group->particles();
+ const int count = particles.count();
+ for (int left = 0; left < count; ++left) {
+ for (int right = left+1; right < count; ++right) {
+ if (termMatches(particles.at(left)->term(), particles.at(right)->term(), namePool))
+ return false;
+ }
+ }
+ return true;
+}
+
+bool XsdParticleChecker::subsumes(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &derivedParticle, const XsdSchemaContext::Ptr &context, QString &errorMsg)
+{
+ /**
+ * The algorithm is implemented like described in http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html#S2.3
+ */
+
+ const NamePool::Ptr namePool(context->namePool());
+
+ XsdStateMachine<XsdTerm::Ptr> baseStateMachine(namePool);
+ XsdStateMachine<XsdTerm::Ptr> derivedStateMachine(namePool);
+
+ // build up state machines for both particles
+ {
+ XsdStateMachineBuilder builder(&baseStateMachine, namePool);
+ const XsdStateMachine<XsdTerm::Ptr>::StateId endState = builder.reset();
+ const XsdStateMachine<XsdTerm::Ptr>::StateId startState = builder.buildParticle(particle, endState);
+ builder.addStartState(startState);
+
+ baseStateMachine = baseStateMachine.toDFA();
+ }
+ {
+ XsdStateMachineBuilder builder(&derivedStateMachine, namePool);
+ const XsdStateMachine<XsdTerm::Ptr>::StateId endState = builder.reset();
+ const XsdStateMachine<XsdTerm::Ptr>::StateId startState = builder.buildParticle(derivedParticle, endState);
+ builder.addStartState(startState);
+
+ derivedStateMachine = derivedStateMachine.toDFA();
+ }
+
+ QHash<XsdTerm::Ptr, XsdParticle::Ptr> particlesHash = XsdStateMachineBuilder::particleLookupMap(particle);
+ particlesHash.unite(XsdStateMachineBuilder::particleLookupMap(derivedParticle));
+
+/*
+ static int counter = 0;
+ {
+ QFile file(QString("/tmp/file_base%1.dot").arg(counter));
+ file.open(QIODevice::WriteOnly);
+ baseStateMachine.outputGraph(&file, QLatin1String("Base"));
+ file.close();
+ }
+ {
+ QFile file(QString("/tmp/file_derived%1.dot").arg(counter));
+ file.open(QIODevice::WriteOnly);
+ derivedStateMachine.outputGraph(&file, QLatin1String("Base"));
+ file.close();
+ }
+ ::system(QString("dot -Tpng /tmp/file_base%1.dot -o/tmp/file_base%1.png").arg(counter).toLatin1().data());
+ ::system(QString("dot -Tpng /tmp/file_derived%1.dot -o/tmp/file_derived%1.png").arg(counter).toLatin1().data());
+*/
+
+ const XsdStateMachine<XsdTerm::Ptr>::StateId baseStartState = baseStateMachine.startState();
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateType> baseStates = baseStateMachine.states();
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > > baseTransitions = baseStateMachine.transitions();
+
+ const XsdStateMachine<XsdTerm::Ptr>::StateId derivedStartState = derivedStateMachine.startState();
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateType> derivedStates = derivedStateMachine.states();
+ const QHash<XsdStateMachine<XsdTerm::Ptr>::StateId, QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > > derivedTransitions = derivedStateMachine.transitions();
+
+ // @see http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html#S2.3.1
+
+ // define working set
+ QList<QPair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId> > workSet;
+ QList<QPair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId> > processedSet;
+
+ // 1) fill working set initially with start states
+ workSet.append(qMakePair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId>(baseStartState, derivedStartState));
+ processedSet.append(qMakePair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId>(baseStartState, derivedStartState));
+
+ while (!workSet.isEmpty()) { // while there are state sets to process
+
+ // 3) dequeue on state set
+ const QPair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId> set = workSet.takeFirst();
+
+ const QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > derivedTrans = derivedTransitions.value(set.second);
+ QHashIterator<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > derivedIt(derivedTrans);
+
+ const QHash<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > baseTrans = baseTransitions.value(set.first);
+
+ while (derivedIt.hasNext()) {
+ derivedIt.next();
+
+ bool found = false;
+ QHashIterator<XsdTerm::Ptr, QVector<XsdStateMachine<XsdTerm::Ptr>::StateId> > baseIt(baseTrans);
+ while (baseIt.hasNext()) {
+ baseIt.next();
+ if (derivedTermValid(baseIt.key(), derivedIt.key(), particlesHash, context, errorMsg)) {
+ const QPair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId> endSet =
+ qMakePair<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateId>(baseIt.value().first(), derivedIt.value().first());
+ if (!processedSet.contains(endSet) && !workSet.contains(endSet)) {
+ workSet.append(endSet);
+ processedSet.append(endSet);
+ }
+
+ found = true;
+ }
+ }
+
+ if (!found) {
+ return false;
+ }
+ }
+ }
+
+ // 5)
+ QHashIterator<XsdStateMachine<XsdTerm::Ptr>::StateId, XsdStateMachine<XsdTerm::Ptr>::StateType> it(derivedStates);
+ while (it.hasNext()) {
+ it.next();
+
+ if (it.value() == XsdStateMachine<XsdTerm::Ptr>::EndState || it.value() == XsdStateMachine<XsdTerm::Ptr>::StartEndState) {
+ for (int i = 0; i < processedSet.count(); ++i) {
+ if (processedSet.at(i).second == it.key() &&
+ (baseStates.value(processedSet.at(i).first) != XsdStateMachine<XsdTerm::Ptr>::EndState &&
+ baseStates.value(processedSet.at(i).first) != XsdStateMachine<XsdTerm::Ptr>::StartEndState)) {
+ errorMsg = QtXmlPatterns::tr("Derived particle allows content that is not allowed in the base particle.");
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdparticlechecker_p.h b/src/xmlpatterns/schema/qxsdparticlechecker_p.h
new file mode 100644
index 0000000..40c525a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdparticlechecker_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdParticleChecker_H
+#define Patternist_XsdParticleChecker_H
+
+#include "qxsdelement_p.h"
+#include "qxsdparticle_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdwildcard_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class to check validity of particles.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdParticleChecker
+ {
+ public:
+ /**
+ * Checks whether the given @p particle has two or more element
+ * declarations with the same name but different type definitions.
+ */
+ static bool hasDuplicatedElements(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, XsdElement::Ptr &conflictingElement);
+
+ /**
+ * Checks whether the given @p particle is valid according the
+ * UPA (http://www.w3.org/TR/xmlschema-1/#cos-nonambig) constraint.
+ */
+ static bool isUPAConform(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool);
+
+ /**
+ * Checks whether the given @p particle, which must be an xsd:all element,
+ * is valid according the UPA (http://www.w3.org/TR/xmlschema-1/#cos-nonambig) constraint.
+ * For xsd:all elements, we do not want to construct a state machine.
+ */
+ static bool isUPAConformXsdAll(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool);
+
+ /**
+ * Checks whether the given @p particle subsumes the given @p derivedParticle.
+ * (http://www.w3.org/TR/xmlschema-1/#cos-particle-restrict)
+ */
+ static bool subsumes(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &derivedParticle, const XsdSchemaContext::Ptr &context, QString &errorMsg);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdreference.cpp b/src/xmlpatterns/schema/qxsdreference.cpp
new file mode 100644
index 0000000..d98a405
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdreference.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdreference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XsdReference::isReference() const
+{
+ return true;
+}
+
+void XsdReference::setType(Type type)
+{
+ m_type = type;
+}
+
+XsdReference::Type XsdReference::type() const
+{
+ return m_type;
+}
+
+void XsdReference::setReferenceName(const QXmlName &referenceName)
+{
+ m_referenceName = referenceName;
+}
+
+QXmlName XsdReference::referenceName() const
+{
+ return m_referenceName;
+}
+
+void XsdReference::setSourceLocation(const QSourceLocation &location)
+{
+ m_sourceLocation = location;
+}
+
+QSourceLocation XsdReference::sourceLocation() const
+{
+ return m_sourceLocation;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdreference_p.h b/src/xmlpatterns/schema/qxsdreference_p.h
new file mode 100644
index 0000000..028d190
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdreference_p.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdReference_H
+#define Patternist_XsdReference_H
+
+#include "qxsdterm_p.h"
+
+#include <QtXmlPatterns/QSourceLocation>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class for element and group reference resolving.
+ *
+ * For easy resolving of element and group references, we have this class
+ * that can be used as a place holder for the real element or group
+ * object it is referring to.
+ * So whenever the parser detects an element or group reference, it creates
+ * a XsdReference and returns it instead of the XsdElement or XsdModelGroup.
+ * During a later phase, the resolver will look for all XsdReferences
+ * in the schema and will replace them with their referring XsdElement or
+ * XsdModelGroup objects.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdReference : public XsdTerm
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdReference> Ptr;
+
+ /**
+ * Describes the type of the reference.
+ */
+ enum Type
+ {
+ Element, ///< The reference points to an element.
+ ModelGroup ///< The reference points to a model group.
+ };
+
+ /**
+ * Returns always @c true, used to avoid dynamic casts.
+ */
+ virtual bool isReference() const;
+
+ /**
+ * Sets the @p type of the reference.
+ *
+ * @see Type
+ */
+ void setType(Type type);
+
+ /**
+ * Returns the type of the reference.
+ */
+ Type type() const;
+
+ /**
+ * Sets the @p name of the referenced object.
+ *
+ * The name can either be a top-level element declaration
+ * or a top-level group declaration.
+ */
+ void setReferenceName(const QXmlName &ame);
+
+ /**
+ * Returns the name of the referenced object.
+ */
+ QXmlName referenceName() const;
+
+ /**
+ * Sets the source @p location where the reference is located.
+ */
+ void setSourceLocation(const QSourceLocation &location);
+
+ /**
+ * Returns the source location where the reference is located.
+ */
+ QSourceLocation sourceLocation() const;
+
+ private:
+ Type m_type;
+ QXmlName m_referenceName;
+ QSourceLocation m_sourceLocation;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschema.cpp b/src/xmlpatterns/schema/qxsdschema.cpp
new file mode 100644
index 0000000..cb766d1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschema.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschema_p.h"
+
+#include <QtCore/QReadLocker>
+#include <QtCore/QWriteLocker>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchema::XsdSchema(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+{
+}
+
+XsdSchema::~XsdSchema()
+{
+}
+
+NamePool::Ptr XsdSchema::namePool() const
+{
+ return m_namePool;
+}
+
+void XsdSchema::setTargetNamespace(const QString &targetNamespace)
+{
+ m_targetNamespace = targetNamespace;
+}
+
+QString XsdSchema::targetNamespace() const
+{
+ return m_targetNamespace;
+}
+
+void XsdSchema::addElement(const XsdElement::Ptr &element)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_elements.insert(element->name(m_namePool), element);
+}
+
+XsdElement::Ptr XsdSchema::element(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_elements.value(name);
+}
+
+XsdElement::List XsdSchema::elements() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_elements.values();
+}
+
+void XsdSchema::addAttribute(const XsdAttribute::Ptr &attribute)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_attributes.insert(attribute->name(m_namePool), attribute);
+}
+
+XsdAttribute::Ptr XsdSchema::attribute(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_attributes.value(name);
+}
+
+XsdAttribute::List XsdSchema::attributes() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_attributes.values();
+}
+
+void XsdSchema::addType(const SchemaType::Ptr &type)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_types.insert(type->name(m_namePool), type);
+}
+
+SchemaType::Ptr XsdSchema::type(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_types.value(name);
+}
+
+SchemaType::List XsdSchema::types() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_types.values();
+}
+
+XsdSimpleType::List XsdSchema::simpleTypes() const
+{
+ QReadLocker locker(&m_lock);
+
+ XsdSimpleType::List retval;
+
+ const SchemaType::List types = m_types.values();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isSimpleType() && types.at(i)->isDefinedBySchema())
+ retval.append(types.at(i));
+ }
+
+ return retval;
+}
+
+XsdComplexType::List XsdSchema::complexTypes() const
+{
+ QReadLocker locker(&m_lock);
+
+ XsdComplexType::List retval;
+
+ const SchemaType::List types = m_types.values();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema())
+ retval.append(types.at(i));
+ }
+
+ return retval;
+}
+
+void XsdSchema::addAnonymousType(const SchemaType::Ptr &type)
+{
+ const QWriteLocker locker(&m_lock);
+
+ // search for not used anonymous type name
+ QXmlName typeName = type->name(m_namePool);
+ while (m_anonymousTypes.contains(typeName)) {
+ typeName = m_namePool->allocateQName(QString(), QLatin1String("merged_") + m_namePool->stringForLocalName(typeName.localName()), QString());
+ }
+
+ m_anonymousTypes.insert(typeName, type);
+}
+
+SchemaType::List XsdSchema::anonymousTypes() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_anonymousTypes.values();
+}
+
+void XsdSchema::addAttributeGroup(const XsdAttributeGroup::Ptr &group)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_attributeGroups.insert(group->name(m_namePool), group);
+}
+
+XsdAttributeGroup::Ptr XsdSchema::attributeGroup(const QXmlName name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_attributeGroups.value(name);
+}
+
+XsdAttributeGroup::List XsdSchema::attributeGroups() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_attributeGroups.values();
+}
+
+void XsdSchema::addElementGroup(const XsdModelGroup::Ptr &group)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_elementGroups.insert(group->name(m_namePool), group);
+}
+
+XsdModelGroup::Ptr XsdSchema::elementGroup(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_elementGroups.value(name);
+}
+
+XsdModelGroup::List XsdSchema::elementGroups() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_elementGroups.values();
+}
+
+void XsdSchema::addNotation(const XsdNotation::Ptr &notation)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_notations.insert(notation->name(m_namePool), notation);
+}
+
+XsdNotation::Ptr XsdSchema::notation(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_notations.value(name);
+}
+
+XsdNotation::List XsdSchema::notations() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_notations.values();
+}
+
+void XsdSchema::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint)
+{
+ const QWriteLocker locker(&m_lock);
+
+ m_identityConstraints.insert(constraint->name(m_namePool), constraint);
+}
+
+XsdIdentityConstraint::Ptr XsdSchema::identityConstraint(const QXmlName &name) const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_identityConstraints.value(name);
+}
+
+XsdIdentityConstraint::List XsdSchema::identityConstraints() const
+{
+ const QReadLocker locker(&m_lock);
+
+ return m_identityConstraints.values();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschema_p.h b/src/xmlpatterns/schema/qxsdschema_p.h
new file mode 100644
index 0000000..e63324e
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschema_p.h
@@ -0,0 +1,301 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSchema_H
+#define Patternist_XsdSchema_H
+
+#include "qschematype_p.h"
+#include "qxsdannotated_p.h"
+#include "qxsdattribute_p.h"
+#include "qxsdattributegroup_p.h"
+#include "qxsdcomplextype_p.h"
+#include "qxsdelement_p.h"
+#include "qxsdidentityconstraint_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdnotation_p.h"
+#include "qxsdsimpletype_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QReadWriteLock>
+
+/**
+ * @defgroup Patternist_schema XML Schema Processing
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD schema object.
+ *
+ * The class provides access to all components of a parsed XSD.
+ *
+ * @note In the documentation of this class objects, which are direct
+ * children of the <em>schema</em> object, are called top-level objects.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSModel">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchema : public QSharedData, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdSchema> Ptr;
+ typedef QList<XsdSchema::Ptr> List;
+
+ /**
+ * Creates a new schema object.
+ *
+ * @param namePool The namepool that should be used for names of
+ * all schema components.
+ */
+ XsdSchema(const NamePool::Ptr &namePool);
+
+ /**
+ * Destroys the schema object.
+ */
+ ~XsdSchema();
+
+ /**
+ * Returns the namepool that is used for names of
+ * all schema components.
+ */
+ NamePool::Ptr namePool() const;
+
+ /**
+ * Sets the @p targetNamespace of the schema.
+ */
+ void setTargetNamespace(const QString &targetNamespace);
+
+ /**
+ * Returns the target namespace of the schema.
+ */
+ QString targetNamespace() const;
+
+ /**
+ * Adds a new top-level @p element to the schema.
+ *
+ * @param element The new element.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-element">Element Declaration</a>
+ */
+ void addElement(const XsdElement::Ptr &element);
+
+ /**
+ * Returns the top-level element of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ XsdElement::Ptr element(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all top-level elements.
+ */
+ XsdElement::List elements() const;
+
+ /**
+ * Adds a new top-level @p attribute to the schema.
+ *
+ * @param attribute The new attribute.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-attribute">Attribute Declaration</a>
+ */
+ void addAttribute(const XsdAttribute::Ptr &attribute);
+
+ /**
+ * Returns the top-level attribute of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ XsdAttribute::Ptr attribute(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all top-level attributes.
+ */
+ XsdAttribute::List attributes() const;
+
+ /**
+ * Adds a new top-level @p type to the schema.
+ * That can be a simple or a complex type.
+ *
+ * @param type The new type.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-datatype">Simple Type Declaration</a>
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-type">Complex Type Declaration</a>
+ */
+ void addType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the top-level type of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ SchemaType::Ptr type(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all top-level types.
+ */
+ SchemaType::List types() const;
+
+ /**
+ * Returns the list of all top-level simple types.
+ */
+ XsdSimpleType::List simpleTypes() const;
+
+ /**
+ * Returns the list of all top-level complex types.
+ */
+ XsdComplexType::List complexTypes() const;
+
+ /**
+ * Adds an anonymous @p type to the schema.
+ * Anonymous types have no name and are declared
+ * locally inside an element object.
+ *
+ * @param type The new anonymous type.
+ */
+ void addAnonymousType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the list of all anonymous types.
+ */
+ SchemaType::List anonymousTypes() const;
+
+ /**
+ * Adds a new top-level attribute @p group to the schema.
+ *
+ * @param group The new attribute group.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-attributeGroup">Attribute Group Declaration</a>
+ */
+ void addAttributeGroup(const XsdAttributeGroup::Ptr &group);
+
+ /**
+ * Returns the top-level attribute group of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ XsdAttributeGroup::Ptr attributeGroup(const QXmlName name) const;
+
+ /**
+ * Returns the list of all top-level attribute groups.
+ */
+ XsdAttributeGroup::List attributeGroups() const;
+
+ /**
+ * Adds a new top-level element @p group to the schema.
+ *
+ * @param group The new element group.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-namedModelGroup">Element Group Declaration</a>
+ */
+ void addElementGroup(const XsdModelGroup::Ptr &group);
+
+ /**
+ * Returns the top-level element group of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ XsdModelGroup::Ptr elementGroup(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all top-level element groups.
+ */
+ XsdModelGroup::List elementGroups() const;
+
+ /**
+ * Adds a new top-level @p notation to the schema.
+ *
+ * @param notation The new notation.
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#declare-notation">Notation Declaration</a>
+ */
+ void addNotation(const XsdNotation::Ptr &notation);
+
+ /**
+ * Returns the top-level notation of the schema with
+ * the given @p name or an empty pointer if none exist.
+ */
+ XsdNotation::Ptr notation(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all top-level notations.
+ */
+ XsdNotation::List notations() const;
+
+ /**
+ * Adds a new identity @p constraint to the schema.
+ */
+ void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint);
+
+ /**
+ * Returns the identity constraint with the given @p name
+ * or an empty pointer if none exist.
+ */
+ XsdIdentityConstraint::Ptr identityConstraint(const QXmlName &name) const;
+
+ /**
+ * Returns the list of all identity constraints in this schema.
+ */
+ XsdIdentityConstraint::List identityConstraints() const;
+
+ private:
+ NamePool::Ptr m_namePool;
+ QString m_targetNamespace;
+ QHash<QXmlName, XsdElement::Ptr> m_elements;
+ QHash<QXmlName, XsdAttribute::Ptr> m_attributes;
+ QHash<QXmlName, SchemaType::Ptr> m_types;
+ QHash<QXmlName, SchemaType::Ptr> m_anonymousTypes;
+ QHash<QXmlName, XsdAttributeGroup::Ptr> m_attributeGroups;
+ QHash<QXmlName, XsdModelGroup::Ptr> m_elementGroups;
+ QHash<QXmlName, XsdNotation::Ptr> m_notations;
+ QHash<QXmlName, XsdIdentityConstraint::Ptr> m_identityConstraints;
+ mutable QReadWriteLock m_lock;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemachecker.cpp b/src/xmlpatterns/schema/qxsdschemachecker.cpp
new file mode 100644
index 0000000..0d16940
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemachecker.cpp
@@ -0,0 +1,2061 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemachecker_p.h"
+
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qpatternplatform_p.h"
+#include "qqnamevalue_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qvaluefactory_p.h"
+#include "qxsdattributereference_p.h"
+#include "qxsdparticlechecker_p.h"
+#include "qxsdreference_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdschemahelper_p.h"
+#include "qxsdschemaparsercontext_p.h"
+#include "qxsdschematypesfactory_p.h"
+#include "qxsdtypechecker_p.h"
+
+#include "qxsdschemachecker_helper.cpp"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaChecker::XsdSchemaChecker(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext)
+ : m_context(context)
+ , m_namePool(parserContext->namePool())
+ , m_schema(parserContext->schema())
+{
+ setupAllowedAtomicFacets();
+}
+
+XsdSchemaChecker::~XsdSchemaChecker()
+{
+}
+
+/*
+ * This method is called after the resolver has set the base type for every
+ * type and information about deriavtion and 'is simple type vs. is complex type'
+ * are available.
+ */
+void XsdSchemaChecker::basicCheck()
+{
+ // first check that there is no circular inheritance, only the
+ // wxsSuperType is used here
+ checkBasicCircularInheritances();
+
+ // check the basic constraints like simple type can not inherit from complex type etc.
+ checkBasicSimpleTypeConstraints();
+ checkBasicComplexTypeConstraints();
+}
+
+void XsdSchemaChecker::check()
+{
+ checkCircularInheritances();
+ checkInheritanceRestrictions();
+ checkSimpleDerivationRestrictions();
+ checkSimpleTypeConstraints();
+ checkComplexTypeConstraints();
+ checkDuplicatedAttributeUses();
+
+ checkElementConstraints();
+ checkAttributeConstraints();
+ checkAttributeUseConstraints();
+// checkElementDuplicates();
+}
+
+void XsdSchemaChecker::addComponentLocationHash(const ComponentLocationHash &hash)
+{
+ m_componentLocationHash.unite(hash);
+}
+
+/**
+ * Checks whether the @p otherType is the same as @p myType or if one of its
+ * ancestors is the same as @p myType.
+ */
+static bool matchesType(const SchemaType::Ptr &myType, const SchemaType::Ptr &otherType, QSet<SchemaType::Ptr> visitedTypes)
+{
+ bool retval = false;
+
+ if (otherType) {
+ if (visitedTypes.contains(otherType)) {
+ return true;
+ } else {
+ visitedTypes.insert(otherType);
+ }
+ // simple types can have different varieties, so we have to check each of them
+ if (otherType->isSimpleType()) {
+ const XsdSimpleType::Ptr simpleType = otherType;
+ if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
+ // for atomic type we use the same test as in SchemaType::wxsTypeMatches
+ retval = (myType == simpleType ? true : matchesType(myType, simpleType->wxsSuperType(), visitedTypes));
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
+ // for list type we test against the itemType property
+ retval = (myType == simpleType->itemType() ? true : matchesType(myType, simpleType->itemType()->wxsSuperType(), visitedTypes));
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ // for union type we test against each member type
+ const XsdSimpleType::List members = simpleType->memberTypes();
+ for (int i = 0; i < members.count(); ++i) {
+ if (myType == members.at(i) ? true : matchesType(myType, members.at(i)->wxsSuperType(), visitedTypes)) {
+ retval = true;
+ break;
+ }
+ }
+ } else {
+ // reached xsAnySimple type whichs category is None
+ retval = false;
+ }
+ } else {
+ // if no simple type we handle it like in SchemaType::wxsTypeMatches
+ retval = (myType == otherType ? true : matchesType(myType, otherType->wxsSuperType(), visitedTypes));
+ }
+ } else // if otherType is null it doesn't match
+ retval = false;
+
+ return retval;
+}
+
+/**
+ * Checks whether there is a circular inheritance for the union inheritance.
+ */
+static bool hasCircularUnionInheritance(const XsdSimpleType::Ptr &type, const SchemaType::Ptr &otherType, NamePool::Ptr &namePool)
+{
+ if (type == otherType) {
+ return true;
+ }
+
+ if (!otherType->isSimpleType() || !otherType->isDefinedBySchema()) {
+ return false;
+ }
+
+ const XsdSimpleType::Ptr simpleOtherType = otherType;
+
+ if (simpleOtherType->category() == XsdSimpleType::SimpleTypeUnion) {
+ const XsdSimpleType::List memberTypes = simpleOtherType->memberTypes();
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ if (otherType->wxsSuperType() == type) {
+ return true;
+ }
+ if (hasCircularUnionInheritance(type, memberTypes.at(i), namePool)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static inline bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet<SchemaType::Ptr> &visitedTypes, SchemaType::Ptr &conflictingType)
+{
+ if (!otherType)
+ return false;
+
+ if (visitedTypes.contains(otherType)) { // inheritance loop detected
+ conflictingType = otherType;
+ return true;
+ } else {
+ visitedTypes.insert(otherType);
+ }
+
+ if (type == otherType)
+ return true;
+
+ return wxsTypeMatches(type, otherType->wxsSuperType(), visitedTypes, conflictingType);
+}
+
+void XsdSchemaChecker::checkBasicCircularInheritances()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+ const QSourceLocation location = sourceLocationForType(type);
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 3)
+
+ // check normal base type inheritance
+ QSet<SchemaType::Ptr> visitedTypes;
+ SchemaType::Ptr conflictingType;
+
+ if (wxsTypeMatches(type, type->wxsSuperType(), visitedTypes, conflictingType)) {
+ if (conflictingType)
+ m_context->error(QtXmlPatterns::tr("%1 has inheritance loop in its base type %2.")
+ .arg(formatType(m_namePool, type))
+ .arg(formatType(m_namePool, conflictingType)),
+ XsdSchemaContext::XSDError, location);
+ else
+ m_context->error(QtXmlPatterns::tr("Circular inheritance of base type %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
+
+ return;
+ }
+ }
+}
+
+void XsdSchemaChecker::checkCircularInheritances()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+ const QSourceLocation location = sourceLocationForType(type);
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 3)
+
+ // check normal base type inheritance
+ QSet<SchemaType::Ptr> visitedTypes;
+ if (matchesType(type, type->wxsSuperType(), visitedTypes)) {
+ m_context->error(QtXmlPatterns::tr("Circular inheritance of base type %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // check union member inheritance
+ if (type->isSimpleType() && type->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleType = type;
+ if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ const XsdSimpleType::List memberTypes = simpleType->memberTypes();
+ for (int j = 0; j < memberTypes.count(); ++j) {
+ if (hasCircularUnionInheritance(simpleType, memberTypes.at(j), m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Circular inheritance of union %1.").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkInheritanceRestrictions()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+ const QSourceLocation location = sourceLocationForType(type);
+
+ // check inheritance restrictions given by final property of base class
+ const SchemaType::Ptr baseType = type->wxsSuperType();
+ if (baseType->isDefinedBySchema()) {
+ if ((type->derivationMethod() == SchemaType::DerivationRestriction) && (baseType->derivationConstraints() & SchemaType::RestrictionConstraint)) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by restriction as the latter defines it as final.")
+ .arg(formatType(m_namePool, type))
+ .arg(formatType(m_namePool, baseType)), XsdSchemaContext::XSDError, location);
+ return;
+ } else if ((type->derivationMethod() == SchemaType::DerivationExtension) && (baseType->derivationConstraints() & SchemaType::ExtensionConstraint)) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by extension as the latter defines it as final.")
+ .arg(formatType(m_namePool, type))
+ .arg(formatType(m_namePool, baseType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkBasicSimpleTypeConstraints()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (!type->isSimpleType())
+ continue;
+
+ const XsdSimpleType::Ptr simpleType = type;
+
+ const QSourceLocation location = sourceLocation(simpleType);
+
+ // check inheritance restrictions of simple type defined by schema constraints
+ const SchemaType::Ptr baseType = simpleType->wxsSuperType();
+
+ if (baseType->isComplexType() && (simpleType->name(m_namePool) != BuiltinTypes::xsAnySimpleType->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Base type of simple type %1 cannot be complex type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, baseType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (baseType == BuiltinTypes::xsAnyType) {
+ if (type->name(m_namePool) != BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 cannot have direct base type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, BuiltinTypes::xsAnyType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkSimpleTypeConstraints()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (!type->isSimpleType())
+ continue;
+
+ const XsdSimpleType::Ptr simpleType = type;
+
+ const QSourceLocation location = sourceLocation(simpleType);
+
+ if (simpleType->category() == XsdSimpleType::None) {
+ // additional checks
+ // check that no user defined type has xs:AnySimpleType as base type (except xs:AnyAtomicType)
+ if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
+ if (simpleType->name(m_namePool) != BuiltinTypes::xsAnyAtomicType->name(m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 is not allowed to have base type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleType->wxsSuperType())),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ // check that no user defined type has xs:AnyAtomicType as base type
+ if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnyAtomicType->name(m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 is not allowed to have base type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleType->wxsSuperType())),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e37310
+ if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
+ // 1.1
+ if ((simpleType->wxsSuperType()->category() != XsdSimpleType::SimpleTypeAtomic) && (simpleType->name(m_namePool) != BuiltinTypes::xsAnyAtomicType->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 can only have simple atomic type as base type.")
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ }
+ // 1.2
+ if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 cannot derive from %2 as the latter defines restriction as final.")
+ .arg(formatType(m_namePool, simpleType->wxsSuperType()))
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ }
+
+ // 1.3
+ // checked by checkConstrainingFacets already
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
+ const AnySimpleType::Ptr itemType = simpleType->itemType();
+
+ // 2.1 or @see http://www.w3.org/TR/xmlschema-2/#cos-list-of-atomic
+ if (itemType->category() != SchemaType::SimpleTypeAtomic && itemType->category() != SchemaType::SimpleTypeUnion) {
+ m_context->error(QtXmlPatterns::tr("Variety of item type of %1 must be either atomic or union.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.1 second part
+ if (itemType->category() == SchemaType::SimpleTypeUnion && itemType->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleItemType = itemType;
+ const AnySimpleType::List memberTypes = simpleItemType->memberTypes();
+ for (int j = 0; j < memberTypes.count(); ++j) {
+ if (memberTypes.at(j)->category() != SchemaType::SimpleTypeAtomic) {
+ m_context->error(QtXmlPatterns::tr("Variety of member types of %1 must be atomic.").arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+
+ // 2.2.1
+ if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
+ if (itemType->isSimpleType() && itemType->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleItemType = itemType;
+
+ // 2.2.1.1
+ if (simpleItemType->derivationConstraints() & XsdSimpleType::ListConstraint) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by list as the latter defines it as final.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2.1.2
+ const XsdFacet::Hash facets = simpleType->facets();
+ XsdFacet::HashIterator it(facets);
+
+ bool invalidFacetFound = false;
+ while (it.hasNext()) {
+ it.next();
+ if (it.key() != XsdFacet::WhiteSpace) {
+ invalidFacetFound = true;
+ break;
+ }
+ }
+
+ if (invalidFacetFound) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 is only allowed to have %2 facet.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatKeyword("whiteSpace")),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ } else { // 2.2.2
+ // 2.2.2.1
+ if (simpleType->wxsSuperType()->category() != XsdSimpleType::SimpleTypeList) {
+ m_context->error(QtXmlPatterns::tr("Base type of simple type %1 must have variety of type list.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2.2.2
+ if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) {
+ m_context->error(QtXmlPatterns::tr("Base type of simple type %1 has defined derivation by restriction as final.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2.2.3
+ if (!XsdSchemaHelper::isSimpleDerivationOk(itemType, XsdSimpleType::Ptr(simpleType->wxsSuperType())->itemType(), SchemaType::DerivationConstraints())) {
+ m_context->error(QtXmlPatterns::tr("Item type of base type does not match item type of %1.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2.2.4
+ const XsdFacet::Hash facets = simpleType->facets();
+ XsdFacet::HashIterator it(facets);
+
+ bool invalidFacetFound = false;
+ XsdFacet::Type invalidFacetType = XsdFacet::None;
+ while (it.hasNext()) {
+ it.next();
+ const XsdFacet::Type facetType = it.key();
+ if (facetType != XsdFacet::Length &&
+ facetType != XsdFacet::MinimumLength &&
+ facetType != XsdFacet::MaximumLength &&
+ facetType != XsdFacet::WhiteSpace &&
+ facetType != XsdFacet::Pattern &&
+ facetType != XsdFacet::Enumeration) {
+ invalidFacetType = facetType;
+ invalidFacetFound = true;
+ break;
+ }
+ }
+
+ if (invalidFacetFound) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 contains not allowed facet type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatKeyword(XsdFacet::typeName(invalidFacetType))),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2.2.5
+ // TODO: check value constraints
+ }
+
+
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ const AnySimpleType::List memberTypes = simpleType->memberTypes();
+
+ if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) { // 3.1.1
+ // 3.3.1.1
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ const AnySimpleType::Ptr memberType = memberTypes.at(i);
+
+ if (memberType->derivationConstraints() & XsdSimpleType::UnionConstraint) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by union as the latter defines it as final.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, memberType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+
+ // 3.3.1.2
+ if (!simpleType->facets().isEmpty()) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to have any facets.")
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ } else {
+ // 3.1.2.1
+ if (simpleType->wxsSuperType()->category() != SchemaType::SimpleTypeUnion) {
+ m_context->error(QtXmlPatterns::tr("Base type %1 of simple type %2 must have variety of union.")
+ .arg(formatType(m_namePool, simpleType->wxsSuperType()))
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 3.1.2.2
+ if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::DerivationRestriction) {
+ m_context->error(QtXmlPatterns::tr("Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute.")
+ .arg(formatType(m_namePool, simpleType->wxsSuperType()))
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatAttribute("final")),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ //3.1.2.3
+ if (simpleType->wxsSuperType()->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleBaseType(simpleType->wxsSuperType());
+
+ AnySimpleType::List baseMemberTypes = simpleBaseType->memberTypes();
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ const AnySimpleType::Ptr memberType = memberTypes.at(i);
+ const AnySimpleType::Ptr baseMemberType = baseMemberTypes.at(i);
+
+ if (!XsdSchemaHelper::isSimpleDerivationOk(memberType, baseMemberType, SchemaType::DerivationConstraints())) {
+ m_context->error(QtXmlPatterns::tr("Member type %1 cannot be derived from member type %2 of %3's base type %4.")
+ .arg(formatType(m_namePool, memberType))
+ .arg(formatType(m_namePool, baseMemberType))
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleBaseType)),
+ XsdSchemaContext::XSDError, location);
+ }
+ }
+ }
+
+ // 3.1.2.4
+ const XsdFacet::Hash facets = simpleType->facets();
+ XsdFacet::HashIterator it(facets);
+
+ bool invalidFacetFound = false;
+ XsdFacet::Type invalidFacetType = XsdFacet::None;
+ while (it.hasNext()) {
+ it.next();
+ const XsdFacet::Type facetType = it.key();
+ if (facetType != XsdFacet::Pattern &&
+ facetType != XsdFacet::Enumeration) {
+ invalidFacetType = facetType;
+ invalidFacetFound = true;
+ break;
+ }
+ }
+
+ if (invalidFacetFound) {
+ m_context->error(QtXmlPatterns::tr("Simple type %1 contains not allowed facet type %2.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatKeyword(XsdFacet::typeName(invalidFacetType))),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 3.1.2.5
+ // TODO: check value constraints
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkBasicComplexTypeConstraints()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (!type->isComplexType() || !type->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = type;
+
+ const QSourceLocation location = sourceLocation(complexType);
+
+ // check inheritance restrictions of complex type defined by schema constraints
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 2)
+ if (baseType->isSimpleType() && (complexType->derivationMethod() != XsdComplexType::DerivationExtension)) {
+ m_context->error(QtXmlPatterns::tr("Derivation method of %1 must be extension because the base type %2 is a simple type.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+}
+
+void XsdSchemaChecker::checkComplexTypeConstraints()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (!type->isComplexType() || !type->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = type;
+
+ const QSourceLocation location = sourceLocation(complexType);
+
+ if (complexType->contentType()->particle()) {
+ XsdElement::Ptr duplicatedElement;
+ if (XsdParticleChecker::hasDuplicatedElements(complexType->contentType()->particle(), m_namePool, duplicatedElement)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 has duplicated element %2 in its content model.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatKeyword(duplicatedElement->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (!XsdParticleChecker::isUPAConform(complexType->contentType()->particle(), m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 has non-deterministic content.")
+ .arg(formatType(m_namePool, complexType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+
+ // check inheritance restrictions of complex type defined by schema constraints
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-extends
+ if (complexType->derivationMethod() == XsdComplexType::DerivationExtension) {
+ if (baseType->isComplexType() && baseType->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexBaseType = baseType;
+
+ // we can skip 1.1 here, as it is tested in checkInheritanceRestrictions() already
+
+ // 1.2 and 1.3
+ QString errorMsg;
+ if (!XsdSchemaHelper::isValidAttributeUsesExtension(complexType->attributeUses(), complexBaseType->attributeUses(),
+ complexType->attributeWildcard(), complexBaseType->attributeWildcard(), m_context, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 1.4
+ bool validContentType = false;
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (complexType->contentType()->simpleType() == complexBaseType->contentType()->simpleType()) {
+ validContentType = true; // 1.4.1
+ }
+ } else if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
+ validContentType = true; // 1.4.2
+ } else { // 1.4.3
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) { // 1.4.3.1
+ if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
+ validContentType = true; // 1.4.3.2.1
+ } else { // 1.4.3.2.2
+ if (complexType->contentType()->particle()) { // our own check
+ if ((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) ||
+ (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) { // 1.4.3.2.2.1
+ if (isValidParticleExtension(complexType->contentType()->particle(), complexBaseType->contentType()->particle())) {
+ validContentType = true; // 1.4.3.2.2.2
+ }
+ }
+ }
+ // 1.4.3.2.2.3 and 1.4.3.2.2.4 handle 'open content' that we do not support yet
+ }
+ }
+ }
+
+ // 1.5 WTF?!?
+
+ if (!validContentType) {
+ m_context->error(QtXmlPatterns::tr("Content model of complex type %1 is not a valid extension of content model of %2.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, complexBaseType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ } else if (baseType->isSimpleType()) {
+ // 2.1
+ if (complexType->contentType()->variety() != XsdComplexType::ContentType::Simple) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 must have simple content.")
+ .arg(formatType(m_namePool, complexType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (complexType->contentType()->simpleType() != baseType) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 must have the same simple type as its base class %2.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // 2.2 tested in checkInheritanceRestrictions() already
+ }
+ } else if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) {
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e21402
+ const SchemaType::Ptr baseType(complexType->wxsSuperType());
+
+ bool derivationOk = false;
+ QString errorMsg;
+
+ // we can partly skip 1 here, as it is tested in checkInheritanceRestrictions() already
+ if (baseType->isComplexType()) {
+
+ // 2.1
+ if (baseType->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) {
+ derivationOk = true;
+ }
+
+ if (baseType->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexBaseType(baseType);
+
+ // 2.2.1
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ // 2.2.2.1
+ if (XsdSchemaHelper::isSimpleDerivationOk(complexType->contentType()->simpleType(), complexBaseType->contentType()->simpleType(), SchemaType::DerivationConstraints()))
+ derivationOk = true;
+
+ // 2.2.2.2
+ if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
+ if (XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle()))
+ derivationOk = true;
+ }
+ }
+
+ // 2.3.1
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
+ // 2.3.2.1
+ if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty)
+ derivationOk = true;
+
+ // 2.3.2.2
+ if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
+ if (XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle()))
+ derivationOk = true;
+ }
+ }
+
+ // 2.4.1.1
+ if (((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) &&
+ (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) ||
+ // 2.4.1.2
+ (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {
+
+ // 2.4.2
+ if (XsdParticleChecker::subsumes(complexBaseType->contentType()->particle(), complexType->contentType()->particle(), m_context, errorMsg))
+ derivationOk = true;
+ }
+ }
+ }
+
+ if (!derivationOk) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 cannot be derived from base type %2%3.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType))
+ .arg(errorMsg.isEmpty() ? QString() : QLatin1String(": ") + errorMsg),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (baseType->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexBaseType(baseType);
+
+ QString errorMsg;
+ if (!XsdSchemaHelper::isValidAttributeUsesRestriction(complexType->attributeUses(), complexBaseType->attributeUses(),
+ complexType->attributeWildcard(), complexBaseType->attributeWildcard(), m_context, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+
+ // check that complex type with simple content is not allowed to inherit from
+ // built in complex type xs:AnyType
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (baseType->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 with simple content cannot be derived from complex base type %2.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkSimpleDerivationRestrictions()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (type->isComplexType())
+ continue;
+
+ if (type->category() != SchemaType::SimpleTypeList && type->category() != SchemaType::SimpleTypeUnion)
+ continue;
+
+ const XsdSimpleType::Ptr simpleType = type;
+ const QSourceLocation location = sourceLocation(simpleType);
+
+ // check all simple types derived by list
+ if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
+ const AnySimpleType::Ptr itemType = simpleType->itemType();
+
+ if (itemType->isComplexType()) {
+ m_context->error(QtXmlPatterns::tr("Item type of simple type %1 cannot be a complex type.")
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+
+ if (itemType->isSimpleType() && itemType->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleItemType = itemType;
+ if (simpleItemType->derivationConstraints() & XsdSimpleType::ListConstraint) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by list as the latter defines it as final.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleItemType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#cos-list-of-atomic
+ if (itemType->category() != SchemaType::SimpleTypeAtomic && itemType->category() != SchemaType::SimpleTypeUnion) {
+ m_context->error(QtXmlPatterns::tr("Variety of item type of %1 must be either atomic or union.").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (itemType->category() == SchemaType::SimpleTypeUnion && itemType->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleItemType = itemType;
+ const AnySimpleType::List memberTypes = simpleItemType->memberTypes();
+ for (int j = 0; j < memberTypes.count(); ++j) {
+ if (memberTypes.at(j)->category() != SchemaType::SimpleTypeAtomic) {
+ m_context->error(QtXmlPatterns::tr("Variety of member types of %1 must be atomic.").arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+ }
+
+ // check all simple types derived by union
+ if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ const AnySimpleType::List memberTypes = simpleType->memberTypes();
+
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ const AnySimpleType::Ptr memberType = memberTypes.at(i);
+
+ if (memberType->isComplexType()) {
+ m_context->error(QtXmlPatterns::tr("Member type of simple type %1 cannot be a complex type.")
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#cos-no-circular-unions
+ if (simpleType->name(m_namePool) == memberType->name(m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to have a member type with the same name as itself.")
+ .arg(formatType(m_namePool, simpleType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+
+ if (memberType->isSimpleType() && memberType->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleMemberType = memberType;
+ if (simpleMemberType->derivationConstraints() & XsdSimpleType::UnionConstraint) {
+ m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by union as the latter defines it as final.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatType(m_namePool, simpleMemberType)),
+ XsdSchemaContext::XSDError, location);
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkConstrainingFacets()
+{
+ // first the global simple types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (!(types.at(i)->isSimpleType()) || !(types.at(i)->isDefinedBySchema()))
+ continue;
+
+ const XsdSimpleType::Ptr simpleType = types.at(i);
+ checkConstrainingFacets(simpleType->facets(), simpleType);
+ }
+
+ // and afterwards all anonymous simple types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (!(anonymousTypes.at(i)->isSimpleType()) || !(anonymousTypes.at(i)->isDefinedBySchema()))
+ continue;
+
+ const XsdSimpleType::Ptr simpleType = anonymousTypes.at(i);
+ checkConstrainingFacets(simpleType->facets(), simpleType);
+ }
+}
+
+void XsdSchemaChecker::checkConstrainingFacets(const XsdFacet::Hash &facets, const XsdSimpleType::Ptr &simpleType)
+{
+ if (facets.isEmpty())
+ return;
+
+ SchemaType::Ptr comparableBaseType;
+ if (!simpleType->wxsSuperType()->isDefinedBySchema())
+ comparableBaseType = simpleType->wxsSuperType();
+ else
+ comparableBaseType = simpleType->primitiveType();
+
+ const XsdSchemaSourceLocationReflection reflection(sourceLocation(simpleType));
+
+ // start checks
+ if (facets.contains(XsdFacet::Length)) {
+ const XsdFacet::Ptr lengthFacet = facets.value(XsdFacet::Length);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr lengthValue = lengthFacet->value();
+
+ // @see http://www.w3.org/TR/xmlschema-2/#length-minLength-maxLength
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ const XsdFacet::Ptr minLengthFacet = facets.value(XsdFacet::MinimumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr minLengthValue = minLengthFacet->value();
+
+ bool foundSuperMinimumLength = false;
+ SchemaType::Ptr baseType = simpleType->wxsSuperType();
+ while (baseType) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(baseType);
+ if (baseFacets.contains(XsdFacet::MinimumLength) && !baseFacets.contains(XsdFacet::Length)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr superValue(baseFacets.value(XsdFacet::MinimumLength)->value());
+ if (minLengthValue->toInteger() == superValue->toInteger()) {
+ foundSuperMinimumLength = true;
+ break;
+ }
+ }
+
+ baseType = baseType->wxsSuperType();
+ }
+
+ if ((minLengthValue->toInteger() > lengthValue->toInteger()) || !foundSuperMinimumLength) {
+ m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
+ .arg(formatKeyword("length"))
+ .arg(formatKeyword("minLength")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#length-minLength-maxLength
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();
+
+ bool foundSuperMaximumLength = false;
+ SchemaType::Ptr baseType = simpleType->wxsSuperType();
+ while (baseType) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(baseType);
+ if (baseFacets.contains(XsdFacet::MaximumLength) && !baseFacets.contains(XsdFacet::Length)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr superValue(baseFacets.value(XsdFacet::MaximumLength)->value());
+ if (maxLengthValue->toInteger() == superValue->toInteger()) {
+ foundSuperMaximumLength = true;
+ break;
+ }
+ }
+
+ baseType = baseType->wxsSuperType();
+ }
+
+ if ((maxLengthValue->toInteger() < lengthValue->toInteger()) || !foundSuperMaximumLength) {
+ m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
+ .arg(formatKeyword("length"))
+ .arg(formatKeyword("maxLength")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#length-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::Length)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacets.value(XsdFacet::Length)->value();
+ if (lengthValue->toInteger() != baseValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must have the same value as %2 facet of base type.")
+ .arg(formatKeyword("length"))
+ .arg(formatKeyword("length")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ const XsdFacet::Ptr minLengthFacet = facets.value(XsdFacet::MinimumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr minLengthValue = minLengthFacet->value();
+
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minLength-less-than-equal-to-maxLength
+ if (maxLengthValue->toInteger() < minLengthValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet.")
+ .arg(formatKeyword("minLength"))
+ .arg(formatKeyword("maxLength")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minLength-valid-restriction
+ //TODO: check parent facets
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minLength-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MinimumLength)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacets.value(XsdFacet::MinimumLength)->value();
+ if (minLengthValue->toInteger() < baseValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be equal or greater than %2 facet of base type.")
+ .arg(formatKeyword("minLength"))
+ .arg(formatKeyword("minLength")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr maxLengthValue = maxLengthFacet->value();
+
+ // @see http://www.w3.org/TR/xmlschema-2/#maxLength-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MaximumLength)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue(baseFacets.value(XsdFacet::MaximumLength)->value());
+ if (maxLengthValue->toInteger() > baseValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("maxLength"))
+ .arg(formatKeyword("maxLength")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ // we keep the patterns in separated facets
+ // @see http://www.w3.org/TR/xmlschema-2/#src-multiple-patterns
+
+ // @see http://www.w3.org/TR/xmlschema-2/#cvc-pattern-valid
+ const XsdFacet::Ptr patternFacet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = patternFacet->multiValue();
+
+ for (int i = 0; i < multiValue.count(); ++i) {
+ const DerivedString<TypeString>::Ptr value = multiValue.at(i);
+ const QRegExp exp = PatternPlatform::parsePattern(value->stringValue(), m_context, &reflection);
+ if (!exp.isValid()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet contains invalid regular expression").arg(formatKeyword("pattern.")), XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ // @see http://www.w3.org/TR/xmlschema-2/#src-multiple-enumerations
+
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+
+ if (BuiltinTypes::xsNOTATION->wxsTypeMatches(simpleType)) {
+ const AtomicValue::List notationNames = facet->multiValue();
+ for (int k = 0; k < notationNames.count(); ++k) {
+ const QNameValue::Ptr notationName = notationNames.at(k);
+ if (!m_schema->notation(notationName->qName())) {
+ m_context->error(QtXmlPatterns::tr("Unknown notation %1 used in %2 facet.")
+ .arg(formatKeyword(m_namePool, notationName->qName()))
+ .arg(formatKeyword("enumeration")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ }
+ }
+ } else if (BuiltinTypes::xsQName->wxsTypeMatches(simpleType)) {
+ } else {
+ const XsdTypeChecker checker(m_context, QVector<QXmlName>(), sourceLocation(simpleType));
+
+ const AnySimpleType::Ptr baseType = simpleType->wxsSuperType();
+ const XsdFacet::Hash baseFacets = XsdTypeChecker::mergedFacetsForType(baseType, m_context);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ for (int k = 0; k < multiValue.count(); ++k) {
+ const QString stringValue = multiValue.at(k)->as<DerivedString<TypeString> >()->stringValue();
+ const QString actualValue = XsdTypeChecker::normalizedValue(stringValue, baseFacets);
+
+ QString errorMsg;
+ if (!checker.isValidString(actualValue, baseType, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet contains invalid value %2: %3.")
+ .arg(formatKeyword("enumeration"))
+ .arg(formatData(stringValue))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::WhiteSpace)) {
+ const XsdFacet::Ptr whiteSpaceFacet = facets.value(XsdFacet::WhiteSpace);
+ const DerivedString<TypeString>::Ptr whiteSpaceValue = whiteSpaceFacet->value();
+
+ // @see http://www.w3.org/TR/xmlschema-2/#whiteSpace-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::WhiteSpace)) {
+ const QString value = whiteSpaceValue->stringValue();
+ const QString baseValue = DerivedString<TypeString>::Ptr(baseFacets.value(XsdFacet::WhiteSpace)->value())->stringValue();
+ if (value == XsdSchemaToken::toString(XsdSchemaToken::Replace) || value == XsdSchemaToken::toString(XsdSchemaToken::Preserve)) {
+ if (baseValue == XsdSchemaToken::toString(XsdSchemaToken::Collapse)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet cannot be %2 or %3 if %4 facet of base type is %5.")
+ .arg(formatKeyword("whiteSpace"))
+ .arg(formatData("replace"))
+ .arg(formatData("preserve"))
+ .arg(formatKeyword("whiteSpace"))
+ .arg(formatData("collapse")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ if (value == XsdSchemaToken::toString(XsdSchemaToken::Preserve) && baseValue == XsdSchemaToken::toString(XsdSchemaToken::Replace)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet cannot be %2 if %3 facet of base type is %4.")
+ .arg(formatKeyword("whiteSpace"))
+ .arg(formatData("preserve"))
+ .arg(formatKeyword("whiteSpace"))
+ .arg(formatData("replace")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumInclusive);
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-less-than-equal-to-maxInclusive
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumInclusive);
+
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#maxInclusive-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("maxInclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
+ .arg(formatKeyword("maxInclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumExclusive);
+
+ // @see http://www.w3.org/TR/xmlschema-2/#maxInclusive-maxExclusive
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet and %2 facet cannot appear together.")
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-less-than-equal-to-maxExclusive
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#maxExclusive-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("minInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("minExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumExclusive);
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-minExclusive
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet and %2 facet cannot appear together.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("minInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-less-than-maxInclusive
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be greater than or equal to %2 facet of base type.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("minExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumInclusive);
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-less-than-maxExclusive
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, maxFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be greater than or equal to %2 facet of base type.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("minInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("minExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("maxInclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ if (baseFacets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive);
+ if (comparableBaseType) {
+ if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type.")
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("maxExclusive")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr totalDigitsFacet = facets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr totalDigitsValue = totalDigitsFacet->value();
+
+ // @see http://www.w3.org/TR/xmlschema-2/#totalDigits-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacet->value();
+
+ if (totalDigitsValue->toInteger() > baseValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("totalDigits"))
+ .arg(formatKeyword("totalDigits")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ if (facets.contains(XsdFacet::FractionDigits)) {
+ const XsdFacet::Ptr fractionDigitsFacet = facets.value(XsdFacet::FractionDigits);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr fractionDigitsValue = fractionDigitsFacet->value();
+
+ // http://www.w3.org/TR/xmlschema-2/#fractionDigits-totalDigits
+ if (facets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr totalDigitsFacet = facets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr totalDigitsValue = totalDigitsFacet->value();
+
+ if (fractionDigitsValue->toInteger() > totalDigitsValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet.")
+ .arg(formatKeyword("fractionDigits"))
+ .arg(formatKeyword("totalDigits")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#fractionDigits-valid-restriction
+ if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) {
+ const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType());
+ if (baseFacets.contains(XsdFacet::FractionDigits)) {
+ const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::FractionDigits);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr baseValue = baseFacet->value();
+
+ if (fractionDigitsValue->toInteger() > baseValue->toInteger()) {
+ m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type.")
+ .arg(formatKeyword("fractionDigits"))
+ .arg(formatKeyword("fractionDigits")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+
+
+ // check whether facets are allowed for simple types variety
+ if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeAtomic) {
+ if (simpleType->primitiveType()) {
+ const QXmlName primitiveTypeName = simpleType->primitiveType()->name(m_namePool);
+ if (m_allowedAtomicFacets.contains(primitiveTypeName)) {
+ const QSet<XsdFacet::Type> allowedFacets = m_allowedAtomicFacets.value(primitiveTypeName);
+ QSet<XsdFacet::Type> availableFacets = facets.keys().toSet();
+
+ if (!availableFacets.subtract(allowedFacets).isEmpty()) {
+ m_context->error(QtXmlPatterns::tr("Simple type contains not allowed facet %1.")
+ .arg(formatKeyword(XsdFacet::typeName(availableFacets.toList().first()))),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ } else if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeList) {
+ if (facets.contains(XsdFacet::MaximumInclusive) || facets.contains(XsdFacet::MinimumInclusive) ||
+ facets.contains(XsdFacet::MaximumExclusive) || facets.contains(XsdFacet::MinimumExclusive) ||
+ facets.contains(XsdFacet::TotalDigits) || facets.contains(XsdFacet::FractionDigits))
+ {
+ m_context->error(QtXmlPatterns::tr("%1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list.")
+ .arg(formatKeyword("maxInclusive"))
+ .arg(formatKeyword("maxExclusive"))
+ .arg(formatKeyword("minInclusive"))
+ .arg(formatKeyword("minExclusive"))
+ .arg(formatKeyword("totalDigits"))
+ .arg(formatKeyword("fractionDigits")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ }
+ } else if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeUnion) {
+ if (facets.contains(XsdFacet::MaximumInclusive) || facets.contains(XsdFacet::MinimumInclusive) ||
+ facets.contains(XsdFacet::MaximumExclusive) || facets.contains(XsdFacet::MinimumExclusive) ||
+ facets.contains(XsdFacet::TotalDigits) || facets.contains(XsdFacet::FractionDigits) ||
+ facets.contains(XsdFacet::MinimumLength) || facets.contains(XsdFacet::MaximumLength) ||
+ facets.contains(XsdFacet::Length) || facets.contains(XsdFacet::WhiteSpace))
+ {
+ m_context->error(QtXmlPatterns::tr("Only %1 and %2 facets are allowed when derived by union.")
+ .arg(formatKeyword("pattern"))
+ .arg(formatKeyword("enumeration")),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ }
+ }
+
+ // check whether value of facet matches the value space of the simple types base type
+ const SchemaType::Ptr baseType = simpleType->wxsSuperType();
+ if (!baseType->isDefinedBySchema()) {
+ const XsdSchemaSourceLocationReflection reflection(sourceLocation(simpleType));
+
+ XsdFacet::HashIterator it(facets);
+ while (it.hasNext()) {
+ it.next();
+ const XsdFacet::Ptr facet = it.value();
+ if (facet->type() == XsdFacet::MaximumInclusive ||
+ facet->type() == XsdFacet::MaximumExclusive ||
+ facet->type() == XsdFacet::MinimumInclusive ||
+ facet->type() == XsdFacet::MinimumExclusive) {
+ const DerivedString<TypeString>::Ptr stringValue = facet->value();
+ const AtomicValue::Ptr value = ValueFactory::fromLexical(stringValue->stringValue(), baseType, m_context, &reflection);
+ if (value->hasError()) {
+ m_context->error(QtXmlPatterns::tr("%1 contains %2 facet with invalid data: %3.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatKeyword(XsdFacet::typeName(facet->type())))
+ .arg(formatData(stringValue->stringValue())),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+
+ // @see http://www.w3.org/TR/xmlschema-2/#enumeration-valid-restriction
+ if (facet->type() == XsdFacet::Enumeration && baseType != BuiltinTypes::xsNOTATION) {
+ const AtomicValue::List multiValue = facet->multiValue();
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString stringValue = DerivedString<TypeString>::Ptr(multiValue.at(j))->stringValue();
+ const AtomicValue::Ptr value = ValueFactory::fromLexical(stringValue, baseType, m_context, &reflection);
+ if (value->hasError()) {
+ m_context->error(QtXmlPatterns::tr("%1 contains %2 facet with invalid data: %3.")
+ .arg(formatType(m_namePool, simpleType))
+ .arg(formatKeyword(XsdFacet::typeName(XsdFacet::Enumeration)))
+ .arg(formatData(stringValue)),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkDuplicatedAttributeUses()
+{
+ // first all global attribute groups
+ const XsdAttributeGroup::List attributeGroups = m_schema->attributeGroups();
+ for (int i = 0; i < attributeGroups.count(); ++i) {
+ const XsdAttributeGroup::Ptr attributeGroup = attributeGroups.at(i);
+ const XsdAttributeUse::List uses = attributeGroup->attributeUses();
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 4)
+ XsdAttribute::Ptr conflictingAttribute;
+ if (hasDuplicatedAttributeUses(uses, conflictingAttribute)) {
+ m_context->error(QtXmlPatterns::tr("Attribute group %1 contains attribute %2 twice.")
+ .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
+ .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 5)
+ if (hasMultipleIDAttributeUses(uses)) {
+ m_context->error(QtXmlPatterns::tr("Attribute group %1 contains two different attributes that both have types derived from %2.")
+ .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
+ return;
+ }
+
+ if (hasConstraintIDAttributeUse(uses, conflictingAttribute)) {
+ m_context->error(QtXmlPatterns::tr("Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3.")
+ .arg(formatKeyword(attributeGroup->displayName(m_namePool)))
+ .arg(formatKeyword(conflictingAttribute->displayName(m_namePool)))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(attributeGroup));
+ return;
+ }
+ }
+
+ // then the global and anonymous complex types
+ SchemaType::List types = m_schema->types();
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = types.at(i);
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 4)
+ XsdAttribute::Ptr conflictingAttribute;
+ if (hasDuplicatedAttributeUses(attributeUses, conflictingAttribute)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 contains attribute %2 twice.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 5)
+ if (hasMultipleIDAttributeUses(attributeUses)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 contains two different attributes that both have types derived from %2.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+
+ if (hasConstraintIDAttributeUse(attributeUses, conflictingAttribute)) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatKeyword(conflictingAttribute->displayName(m_namePool)))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+}
+
+void XsdSchemaChecker::checkElementConstraints()
+{
+ const QSet<XsdElement::Ptr> elements = collectAllElements(m_schema);
+ QSetIterator<XsdElement::Ptr> it(elements);
+ while (it.hasNext()) {
+ const XsdElement::Ptr element = it.next();
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#e-props-correct
+
+ // 2 and xs:ID check
+ if (element->valueConstraint()) {
+ const SchemaType::Ptr type = element->type();
+
+ AnySimpleType::Ptr targetType;
+ if (type->isSimpleType() && type->category() == SchemaType::SimpleTypeAtomic) {
+ targetType = type;
+
+ // if it is a XsdSimpleType, use its primitive type as target type
+ if (type->isDefinedBySchema())
+ targetType = XsdSimpleType::Ptr(type)->primitiveType();
+
+ } else if (type->isComplexType() && type->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexType(type);
+
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ const AnySimpleType::Ptr simpleType = complexType->contentType()->simpleType();
+ if (simpleType->category() == AnySimpleType::SimpleTypeAtomic) {
+ targetType = simpleType;
+
+ if (simpleType->isDefinedBySchema())
+ targetType = XsdSimpleType::Ptr(simpleType)->primitiveType();
+ }
+ } else if (complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed) {
+ m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have a value constraint if its base type is complex.")
+ .arg(formatKeyword(element->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ }
+ if ((targetType == BuiltinTypes::xsID) || BuiltinTypes::xsID->wxsTypeMatches(type)) {
+ m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have a value constraint if its type is derived from %2.")
+ .arg(formatKeyword(element->displayName(m_namePool)))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+
+ if (type->isSimpleType()) {
+ QString errorMsg;
+ if (!isValidValue(element->valueConstraint()->value(), type, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("Value constraint of element %1 is not of elements type: %2.")
+ .arg(formatKeyword(element->displayName(m_namePool)))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ } else if (type->isComplexType() && type->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexType(type);
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ QString errorMsg;
+ if (!isValidValue(element->valueConstraint()->value(), complexType->contentType()->simpleType(), errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("Value constraint of element %1 is not of elements type: %2.")
+ .arg(formatKeyword(element->displayName(m_namePool)))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ }
+ }
+ }
+
+ if (!element->substitutionGroupAffiliations().isEmpty()) {
+ // 3
+ if (!element->scope() || element->scope()->variety() != XsdElement::Scope::Global) {
+ m_context->error(QtXmlPatterns::tr("Element %1 is not allowed to have substitution group affiliation as it is no global element.").arg(formatKeyword(element->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+
+ // 4
+ const XsdElement::List affiliations = element->substitutionGroupAffiliations();
+ for (int i = 0; i < affiliations.count(); ++i) {
+ const XsdElement::Ptr affiliation = affiliations.at(i);
+
+ bool derivationOk = false;
+ if (element->type()->isComplexType() && affiliation->type()->isComplexType()) {
+ if (XsdSchemaHelper::isComplexDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
+ derivationOk = true;
+ }
+ }
+ if (element->type()->isComplexType() && affiliation->type()->isSimpleType()) {
+ if (XsdSchemaHelper::isComplexDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
+ derivationOk = true;
+ }
+ }
+ if (element->type()->isSimpleType()) {
+ if (XsdSchemaHelper::isSimpleDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) {
+ derivationOk = true;
+ }
+ }
+
+ if (!derivationOk) {
+ m_context->error(QtXmlPatterns::tr("Type of element %1 cannot be derived from type of substitution group affiliation.").arg(formatKeyword(element->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ }
+
+ // 5 was checked in XsdSchemaResolver::resolveSubstitutionGroupAffiliations() already
+ }
+ }
+}
+
+void XsdSchemaChecker::checkAttributeConstraints()
+{
+ // all global attributes
+ XsdAttribute::List attributes = m_schema->attributes();
+
+ // and all local attributes
+ SchemaType::List types = m_schema->types();
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ if (!types.at(i)->isComplexType() || !types.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType(types.at(i));
+ const XsdAttributeUse::List uses = complexType->attributeUses();
+ for (int j = 0; j < uses.count(); ++j)
+ attributes.append(uses.at(j)->attribute());
+ }
+
+ for (int i = 0; i < attributes.count(); ++i) {
+ const XsdAttribute::Ptr attribute = attributes.at(i);
+
+ if (!attribute->valueConstraint())
+ continue;
+
+ if (attribute->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Default || attribute->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Fixed) {
+ const SchemaType::Ptr type = attribute->type();
+
+ QString errorMsg;
+ if (!isValidValue(attribute->valueConstraint()->value(), attribute->type(), errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("Value constraint of attribute %1 is not of attributes type: %2.")
+ .arg(formatKeyword(attribute->displayName(m_namePool)))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(attribute));
+ return;
+ }
+ }
+
+ if (BuiltinTypes::xsID->wxsTypeMatches(attribute->type())) {
+ m_context->error(QtXmlPatterns::tr("Attribute %1 has value constraint but has type derived from %2.")
+ .arg(formatKeyword(attribute->displayName(m_namePool)))
+ .arg(formatType(m_namePool, BuiltinTypes::xsID)),
+ XsdSchemaContext::XSDError, sourceLocation(attribute));
+ return;
+ }
+ }
+}
+
+bool XsdSchemaChecker::isValidValue(const QString &stringValue, const AnySimpleType::Ptr &type, QString &errorMsg) const
+{
+ if (BuiltinTypes::xsAnySimpleType->name(m_namePool) == type->name(m_namePool))
+ return true; // no need to check xs:anyType content
+
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(type, m_context);
+ const QString actualValue = XsdTypeChecker::normalizedValue(stringValue, facets);
+
+ const XsdTypeChecker checker(m_context, QVector<QXmlName>(), QSourceLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1));
+ return checker.isValidString(actualValue, type, errorMsg);
+}
+
+void XsdSchemaChecker::checkAttributeUseConstraints()
+{
+ XsdComplexType::List complexTypes;
+
+ SchemaType::List types = m_schema->types();
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+ if (type->isComplexType() && type->isDefinedBySchema())
+ complexTypes.append(XsdComplexType::Ptr(type));
+ }
+
+ for (int i = 0; i < complexTypes.count(); ++i) {
+ const XsdComplexType::Ptr complexType(complexTypes.at(i));
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+ if (!baseType || !baseType->isComplexType() || !baseType->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexBaseType(baseType);
+
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+ QHash<QXmlName, XsdAttributeUse::Ptr> lookupHash;
+ for (int j = 0; j < attributeUses.count(); ++j)
+ lookupHash.insert(attributeUses.at(j)->attribute()->name(m_namePool), attributeUses.at(j));
+
+ const XsdAttributeUse::List baseAttributeUses = complexBaseType->attributeUses();
+ for (int j = 0; j < baseAttributeUses.count(); ++j) {
+ const XsdAttributeUse::Ptr baseAttributeUse = baseAttributeUses.at(j);
+
+ if (lookupHash.contains(baseAttributeUse->attribute()->name(m_namePool))) {
+ const XsdAttributeUse::Ptr attributeUse = lookupHash.value(baseAttributeUse->attribute()->name(m_namePool));
+
+ if (baseAttributeUse->useType() == XsdAttributeUse::RequiredUse) {
+ if (attributeUse->useType() == XsdAttributeUse::OptionalUse || attributeUse->useType() == XsdAttributeUse::ProhibitedUse) {
+ m_context->error(QtXmlPatterns::tr("%1 attribute in derived complex type must be %2 like in base type.")
+ .arg(formatAttribute("use"))
+ .arg(formatData("required")),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+
+ if (baseAttributeUse->valueConstraint()) {
+ if (baseAttributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
+ if (!attributeUse->valueConstraint()) {
+ m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have %2 value constraint like in base type.")
+ .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
+ .arg(formatData("fixed")),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ } else {
+ if (attributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
+ const XsdTypeChecker checker(m_context, QVector<QXmlName>(), sourceLocation(complexType));
+ if (!checker.valuesAreEqual(attributeUse->valueConstraint()->value(), baseAttributeUse->valueConstraint()->value(), attributeUse->attribute()->type())) {
+ m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have the same %2 value constraint like in base type.")
+ .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
+ .arg(formatData("fixed")),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ } else {
+ m_context->error(QtXmlPatterns::tr("Attribute %1 in derived complex type must have %2 value constraint.")
+ .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool)))
+ .arg(formatData("fixed")),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // additional check that process content property of attribute wildcard in derived type is
+ // not weaker than the wildcard in base type
+ const XsdWildcard::Ptr baseWildcard(complexBaseType->attributeWildcard());
+ const XsdWildcard::Ptr derivedWildcard(complexType->attributeWildcard());
+ if (baseWildcard && derivedWildcard) {
+ if (!XsdSchemaHelper::checkWildcardProcessContents(baseWildcard, derivedWildcard)) {
+ m_context->error(QtXmlPatterns::tr("processContent of base wildcard must be weaker than derived wildcard."), XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+ }
+}
+
+void XsdSchemaChecker::checkElementDuplicates()
+{
+ // check all global types...
+ SchemaType::List types = m_schema->types();
+
+ // .. and anonymous types
+ types << m_schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ const SchemaType::Ptr type = types.at(i);
+
+ if (!type->isComplexType() || !type->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType(type);
+
+ if ((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) || (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) {
+ DuplicatedElementMap elementMap;
+ DuplicatedWildcardMap wildcardMap;
+
+ checkElementDuplicates(complexType->contentType()->particle(), elementMap, wildcardMap);
+ }
+ }
+}
+
+void XsdSchemaChecker::checkElementDuplicates(const XsdParticle::Ptr &particle, DuplicatedElementMap &elementMap, DuplicatedWildcardMap &wildcardMap)
+{
+ if (particle->term()->isElement()) {
+ const XsdElement::Ptr element(particle->term());
+
+ if (elementMap.contains(element->name(m_namePool))) {
+ if (element->type() != elementMap.value(element->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Element %1 exists twice with different types.")
+ .arg(formatKeyword(element->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ } else {
+ elementMap.insert(element->name(m_namePool), element->type());
+ }
+
+ // check substitution group affiliation
+ const XsdElement::List substElements = element->substitutionGroupAffiliations();
+ for (int i = 0; i < substElements.count(); ++i) {
+ const XsdElement::Ptr substElement = substElements.at(i);
+ if (elementMap.contains(substElement->name(m_namePool))) {
+ if (substElement->type() != elementMap.value(substElement->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Element %1 exists twice with different types.")
+ .arg(formatKeyword(substElement->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, sourceLocation(element));
+ return;
+ }
+ } else {
+ elementMap.insert(substElement->name(m_namePool), substElement->type());
+ }
+ }
+ } else if (particle->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr group(particle->term());
+ const XsdParticle::List particles = group->particles();
+ for (int i = 0; i < particles.count(); ++i)
+ checkElementDuplicates(particles.at(i), elementMap, wildcardMap);
+ } else if (particle->term()->isWildcard()) {
+ const XsdWildcard::Ptr wildcard(particle->term());
+
+ bool error = false;
+ if (!wildcardMap.contains(wildcard->namespaceConstraint()->variety())) {
+ if (!wildcardMap.isEmpty())
+ error = true;
+ } else {
+ const XsdWildcard::Ptr otherWildcard = wildcardMap.value(wildcard->namespaceConstraint()->variety());
+ if ((wildcard->processContents() != otherWildcard->processContents()) || (wildcard->namespaceConstraint()->namespaces() != otherWildcard->namespaceConstraint()->namespaces()))
+ error = true;
+ }
+
+ if (error) {
+ m_context->error(QtXmlPatterns::tr("Particle contains non-deterministic wildcards."), XsdSchemaContext::XSDError, sourceLocation(wildcard));
+ return;
+ } else {
+ wildcardMap.insert(wildcard->namespaceConstraint()->variety(), wildcard);
+ }
+ }
+}
+
+QSourceLocation XsdSchemaChecker::sourceLocation(const NamedSchemaComponent::Ptr &component) const
+{
+ if (m_componentLocationHash.contains(component)) {
+ return m_componentLocationHash.value(component);
+ } else {
+ QSourceLocation location;
+ location.setLine(1);
+ location.setColumn(1);
+ location.setUri(QString::fromLatin1("dummyUri"));
+
+ return location;
+ }
+}
+
+QSourceLocation XsdSchemaChecker::sourceLocationForType(const SchemaType::Ptr &type) const
+{
+ if (type->isSimpleType())
+ return sourceLocation(XsdSimpleType::Ptr(type));
+ else
+ return sourceLocation(XsdComplexType::Ptr(type));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp b/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp
new file mode 100644
index 0000000..3a44365
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp
@@ -0,0 +1,306 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XsdSchemaChecker::hasDuplicatedAttributeUses(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
+{
+ const int length = list.count();
+
+ for (int i = 0; i < length; ++i) {
+ for (int j = 0; j < length; ++j) {
+ if (i == j)
+ continue;
+
+ if (list.at(i)->attribute()->name(m_namePool) == list.at(j)->attribute()->name(m_namePool)) {
+ conflictingAttribute = list.at(i)->attribute();
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool XsdSchemaChecker::hasMultipleIDAttributeUses(const XsdAttributeUse::List &list) const
+{
+ const int length = list.count();
+
+ bool hasIdDerivedAttribute = false;
+ for (int i = 0; i < length; ++i) {
+ if (BuiltinTypes::xsID->wxsTypeMatches(list.at(i)->attribute()->type())) {
+ if (hasIdDerivedAttribute)
+ return true;
+ else
+ hasIdDerivedAttribute = true;
+ }
+ }
+
+ return false;
+}
+
+bool XsdSchemaChecker::hasConstraintIDAttributeUse(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const
+{
+ const int length = list.count();
+
+ for (int i = 0; i < length; ++i) {
+ const XsdAttributeUse::Ptr attributeUse(list.at(i));
+ if (BuiltinTypes::xsID->wxsTypeMatches(attributeUse->attribute()->type())) {
+ if (attributeUse->valueConstraint()) {
+ conflictingAttribute = attributeUse->attribute();
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool XsdSchemaChecker::particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-particle-extend
+ //TODO: find out what 'properties' of a particle should be checked here...
+
+ if (particle->minimumOccurs() != otherParticle->minimumOccurs())
+ return false;
+
+ if (particle->maximumOccursUnbounded() != otherParticle->maximumOccursUnbounded())
+ return false;
+
+ if (particle->maximumOccurs() != otherParticle->maximumOccurs())
+ return false;
+
+ const XsdTerm::Ptr term = particle->term();
+ const XsdTerm::Ptr otherTerm = otherParticle->term();
+
+ if (term->isElement() && !(otherTerm->isElement()))
+ return false;
+
+ if (term->isModelGroup() && !(otherTerm->isModelGroup()))
+ return false;
+
+ if (term->isWildcard() && !(otherTerm->isWildcard()))
+ return false;
+
+ if (term->isElement()) {
+ const XsdElement::Ptr element = term;
+ const XsdElement::Ptr otherElement = otherTerm;
+
+ if (element->name(m_namePool) != otherElement->name(m_namePool))
+ return false;
+
+ if (element->type()->name(m_namePool) != otherElement->type()->name(m_namePool))
+ return false;
+ }
+
+ if (term->isModelGroup()) {
+ const XsdModelGroup::Ptr group = term;
+ const XsdModelGroup::Ptr otherGroup = otherTerm;
+
+ if (group->particles().count() != otherGroup->particles().count())
+ return false;
+
+ for (int i = 0; i < group->particles().count(); ++i) {
+ if (!particleEqualsRecursively(group->particles().at(i), otherGroup->particles().at(i)))
+ return false;
+ }
+ }
+
+ if (term->isWildcard()) {
+ }
+
+ return true;
+}
+
+bool XsdSchemaChecker::isValidParticleExtension(const XsdParticle::Ptr &extension, const XsdParticle::Ptr &base) const
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-particle-extend
+
+ // 1
+ if (extension == base)
+ return true;
+
+ // 2
+ if (extension->minimumOccurs() == 1 && extension->maximumOccurs() == 1 && extension->maximumOccursUnbounded() == false) {
+ if (extension->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr modelGroup = extension->term();
+ if (modelGroup->compositor() == XsdModelGroup::SequenceCompositor) {
+ if (particleEqualsRecursively(modelGroup->particles().first(), base))
+ return true;
+ }
+ }
+ }
+
+ // 3
+ if (extension->minimumOccurs() == base->minimumOccurs()) { // 3.1
+ if (extension->term()->isModelGroup() && base->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr extensionGroup(extension->term());
+ const XsdModelGroup::Ptr baseGroup(base->term());
+
+ if (extensionGroup->compositor() == XsdModelGroup::AllCompositor && baseGroup->compositor() == XsdModelGroup::AllCompositor) {
+ const XsdParticle::List extensionParticles = extensionGroup->particles();
+ const XsdParticle::List baseParticles = baseGroup->particles();
+ for (int i = 0; i < baseParticles.count() && i < extensionParticles.count(); ++i) {
+ if (baseParticles.at(i) != extensionParticles.at(i))
+ return false;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+QSet<XsdElement::Ptr> collectAllElements(const XsdParticle::Ptr &particle)
+{
+ QSet<XsdElement::Ptr> elements;
+
+ const XsdTerm::Ptr term(particle->term());
+ if (term->isElement()) {
+ elements.insert(XsdElement::Ptr(term));
+ } else if (term->isModelGroup()) {
+ const XsdModelGroup::Ptr group(term);
+
+ for (int i = 0; i < group->particles().count(); ++i)
+ elements.unite(collectAllElements(group->particles().at(i)));
+ }
+
+ return elements;
+}
+
+QSet<XsdElement::Ptr> collectAllElements(const XsdSchema::Ptr &schema)
+{
+ QSet<XsdElement::Ptr> elements;
+
+ // collect global elements
+ const XsdElement::List elementList = schema->elements();
+ for (int i = 0; i < elementList.count(); ++i)
+ elements.insert(elementList.at(i));
+
+ // collect all elements from global groups
+ const XsdModelGroup::List groupList = schema->elementGroups();
+ for (int i = 0; i < groupList.count(); ++i) {
+ const XsdModelGroup::Ptr group(groupList.at(i));
+
+ for (int j = 0; j < group->particles().count(); ++j)
+ elements.unite(collectAllElements(group->particles().at(j)));
+ }
+
+ // collect all elements from complex type definitions
+ SchemaType::List types;
+ types << schema->types() << schema->anonymousTypes();
+
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexType(types.at(i));
+ if (complexType->contentType()->particle())
+ elements.unite(collectAllElements(complexType->contentType()->particle()));
+ }
+ }
+
+ return elements;
+}
+
+bool XsdSchemaChecker::elementSequenceAccepted(const XsdModelGroup::Ptr &sequence, const XsdParticle::Ptr &particle) const
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-accept
+
+ if (particle->term()->isWildcard()) { // 1
+ const XsdWildcard::Ptr wildcard(particle->term());
+
+ // 1.1
+ if ((unsigned int)sequence->particles().count() < particle->minimumOccurs())
+ return false;
+
+ // 1.2
+ if (!particle->maximumOccursUnbounded()) {
+ if ((unsigned int)sequence->particles().count() > particle->maximumOccurs())
+ return false;
+ }
+
+ // 1.3
+ const XsdParticle::List particles(sequence->particles());
+ for (int i = 0; i < particles.count(); ++i) {
+ if (particles.at(i)->term()->isElement()) {
+ if (!XsdSchemaHelper::wildcardAllowsExpandedName(XsdElement::Ptr(particles.at(i)->term())->name(m_namePool), wildcard, m_namePool))
+ return false;
+ }
+ }
+ } else if (particle->term()->isElement()) { // 2
+ const XsdElement::Ptr element(particle->term());
+
+ // 2.1
+ if ((unsigned int)sequence->particles().count() < particle->minimumOccurs())
+ return false;
+
+ // 2.2
+ if (!particle->maximumOccursUnbounded()) {
+ if ((unsigned int)sequence->particles().count() > particle->maximumOccurs())
+ return false;
+ }
+
+ // 2.3
+ const XsdParticle::List particles(sequence->particles());
+ for (int i = 0; i < particles.count(); ++i) {
+ bool isValid = false;
+ if (particles.at(i)->term()->isElement()) {
+ const XsdElement::Ptr seqElement(particles.at(i)->term());
+
+ // 2.3.1
+ if (element->name(m_namePool) == seqElement->name(m_namePool))
+ isValid = true;
+
+ // 2.3.2
+ if (element->scope() && element->scope()->variety() == XsdElement::Scope::Global) {
+ if (!(element->disallowedSubstitutions() & NamedSchemaComponent::SubstitutionConstraint)) {
+ //TODO: continue
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemachecker_p.h b/src/xmlpatterns/schema/qxsdschemachecker_p.h
new file mode 100644
index 0000000..b4966d9
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemachecker_p.h
@@ -0,0 +1,284 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSchemaChecker_H
+#define Patternist_XsdSchemaChecker_H
+
+#include "qschematype_p.h"
+#include "qxsdattribute_p.h"
+#include "qxsdattributegroup_p.h"
+#include "qxsdelement_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdnotation_p.h"
+#include "qxsdschema_p.h"
+#include "qxsdsimpletype_p.h"
+
+#include <QtCore/QExplicitlySharedDataPointer>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class XsdSchemaContext;
+ class XsdSchemaParserContext;
+
+ /**
+ * @short Encapsulates the checking of schema valitity after reference resolving has finished.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaChecker : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdSchemaChecker> Ptr;
+
+ /**
+ * Creates a new schema checker.
+ *
+ * @param context The context that is used for customization.
+ * @param parserContext The context that contains all the data structures.
+ */
+ XsdSchemaChecker(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext);
+
+ /**
+ * Destroys the schema checker.
+ */
+ ~XsdSchemaChecker();
+
+ /**
+ * Starts a basic check process.
+ *
+ * This check only validates the basic super type inheritance
+ * of simple and complex types.
+ */
+ void basicCheck();
+
+ /**
+ * Starts the real check process.
+ */
+ void check();
+
+ /**
+ * Checks the constraining facets of all global and anonymous simple types for validity.
+ */
+ void checkConstrainingFacets();
+
+ /**
+ * Adds the component location hash, so the checker is able to report meaning full
+ * error messages.
+ */
+ void addComponentLocationHash(const QHash<NamedSchemaComponent::Ptr, QSourceLocation> &hash);
+
+ private:
+ void checkSimpleRestrictionBaseType();
+
+ /**
+ * Checks that no simple or complex type inherits itself.
+ */
+ void checkBasicCircularInheritances();
+
+ /**
+ * Checks the advanced circular inheritance.
+ */
+ void checkCircularInheritances();
+
+ /**
+ * Checks for inheritance restrictions given by final or finalDefault
+ * attributes.
+ */
+ void checkInheritanceRestrictions();
+
+ /**
+ * Checks for various constraints for simple types defined by schema.
+ */
+ void checkBasicSimpleTypeConstraints();
+ void checkSimpleTypeConstraints();
+
+ /**
+ * Checks for various constraints for complex types defined by schema.
+ */
+ void checkBasicComplexTypeConstraints();
+ void checkComplexTypeConstraints();
+
+ /**
+ * Checks for list and union derivation restrictions given by final or finalDefault
+ * attributes.
+ */
+ void checkSimpleDerivationRestrictions();
+
+ /**
+ * Checks the set of constraining @p facets that belongs to @p simpleType for validity.
+ */
+ void checkConstrainingFacets(const XsdFacet::Hash &facets, const XsdSimpleType::Ptr &simpleType);
+
+ /**
+ * Checks for duplicated attribute uses (attributes with the same name) inside a complex type.
+ */
+ void checkDuplicatedAttributeUses();
+
+ /**
+ * Check the element constraints.
+ */
+ void checkElementConstraints();
+
+ /**
+ * Check the attribute constraints.
+ */
+ void checkAttributeConstraints();
+
+ /**
+ * Check the attribute use constraints.
+ */
+ void checkAttributeUseConstraints();
+
+ /**
+ * A map used to find duplicated elements inside a model group.
+ */
+ typedef QHash<QXmlName, SchemaType::Ptr> DuplicatedElementMap;
+
+ /**
+ * A map used to find duplicated wildcards inside a model group.
+ */
+ typedef QHash<XsdWildcard::NamespaceConstraint::Variety, XsdWildcard::Ptr> DuplicatedWildcardMap;
+
+ /**
+ * Check for duplicated elements and element wildcards in all complex type particles.
+ */
+ void checkElementDuplicates();
+
+ /**
+ * Check for duplicated elements and element wildcards in the given @p particle.
+ *
+ * @param particle The particle to check.
+ * @param elementMap A map to find the duplicated elements.
+ * @param wildcardMap A map to find the duplicated element wildcards.
+ */
+ void checkElementDuplicates(const XsdParticle::Ptr &particle, DuplicatedElementMap &elementMap, DuplicatedWildcardMap &wildcardMap);
+
+ /**
+ * Setup fast lookup list for allowed facets of atomic simple types.
+ */
+ void setupAllowedAtomicFacets();
+
+ /**
+ * Returns the source location of the given schema @p component or a dummy
+ * source location if the component is not found in the component location hash.
+ */
+ QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const;
+
+ /**
+ * Returns the source location of the given schema @p type or a dummy
+ * source location if the type is not found in the component location hash.
+ */
+ QSourceLocation sourceLocationForType(const SchemaType::Ptr &type) const;
+
+ /**
+ * Checks that the string @p value is valid according the value space of @p type
+ * for the given @p component.
+ */
+ bool isValidValue(const QString &value, const AnySimpleType::Ptr &type, QString &errorMsg) const;
+
+ /**
+ * Returns the list of facets for the given @p type.
+ */
+ XsdFacet::Hash facetsForType(const SchemaType::Ptr &type) const;
+
+ /**
+ * Returns whether the given @p list of attribute uses contains two (or more) attribute
+ * uses that point to attributes with the same name. @p conflictingAttribute
+ * will contain the conflicting attribute in that case.
+ */
+ bool hasDuplicatedAttributeUses(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const;
+
+ /**
+ * Returns whether the given @p list of attribute uses contains two (or more) attribute
+ * uses that have a type inherited by xs:ID.
+ */
+ bool hasMultipleIDAttributeUses(const XsdAttributeUse::List &list) const;
+
+ /**
+ * Returns whether the given @p list of attribute uses contains an attribute
+ * uses that has a type inherited by xs:ID with a value constraint. @p conflictingAttribute
+ * will contain the conflicting attribute in that case.
+ */
+ bool hasConstraintIDAttributeUse(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const;
+
+ /**
+ * Checks whether the @p particle equals the @p otherParticle recursively.
+ */
+ bool particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const;
+
+ /**
+ * Checks whether the @p extension particle is a valid extension of the @p base particle.
+ */
+ bool isValidParticleExtension(const XsdParticle::Ptr &extension, const XsdParticle::Ptr &base) const;
+
+ /**
+ * Checks whether the @p sequence of elements is accepted by the given @p particle.
+ */
+ bool elementSequenceAccepted(const XsdModelGroup::Ptr &sequence, const XsdParticle::Ptr &particle) const;
+
+ QExplicitlySharedDataPointer<XsdSchemaContext> m_context;
+ NamePool::Ptr m_namePool;
+ XsdSchema::Ptr m_schema;
+ QHash<QXmlName, QSet<XsdFacet::Type> > m_allowedAtomicFacets;
+ QHash<NamedSchemaComponent::Ptr, QSourceLocation> m_componentLocationHash;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemachecker_setup.cpp b/src/xmlpatterns/schema/qxsdschemachecker_setup.cpp
new file mode 100644
index 0000000..2d08e11
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemachecker_setup.cpp
@@ -0,0 +1,327 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemachecker_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdSchemaChecker::setupAllowedAtomicFacets()
+{
+ // string
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsString->name(m_namePool), facets);
+ }
+
+ // boolean
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsBoolean->name(m_namePool), facets);
+ }
+
+ // float
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsFloat->name(m_namePool), facets);
+ }
+
+ // double
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsDouble->name(m_namePool), facets);
+ }
+
+ // decimal
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::TotalDigits
+ << XsdFacet::FractionDigits
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsDecimal->name(m_namePool), facets);
+ }
+
+ // duration
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsDuration->name(m_namePool), facets);
+ }
+
+ // dateTime
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsDateTime->name(m_namePool), facets);
+ }
+
+ // time
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsTime->name(m_namePool), facets);
+ }
+
+ // date
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsDate->name(m_namePool), facets);
+ }
+
+ // gYearMonth
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsGYearMonth->name(m_namePool), facets);
+ }
+
+ // gYear
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsGYear->name(m_namePool), facets);
+ }
+
+ // gMonthDay
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsGMonthDay->name(m_namePool), facets);
+ }
+
+ // gDay
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsGDay->name(m_namePool), facets);
+ }
+
+ // gMonth
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::MaximumInclusive
+ << XsdFacet::MaximumExclusive
+ << XsdFacet::MinimumInclusive
+ << XsdFacet::MinimumExclusive
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsGMonth->name(m_namePool), facets);
+ }
+
+ // hexBinary
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsHexBinary->name(m_namePool), facets);
+ }
+
+ // base64Binary
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsBase64Binary->name(m_namePool), facets);
+ }
+
+ // anyURI
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsAnyURI->name(m_namePool), facets);
+ }
+
+ // QName
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsQName->name(m_namePool), facets);
+ }
+
+ // NOTATION
+ {
+ QSet<XsdFacet::Type> facets;
+ facets << XsdFacet::Length
+ << XsdFacet::MinimumLength
+ << XsdFacet::MaximumLength
+ << XsdFacet::Pattern
+ << XsdFacet::Enumeration
+ << XsdFacet::WhiteSpace
+ << XsdFacet::Assertion;
+
+ m_allowedAtomicFacets.insert(BuiltinTypes::xsNOTATION->name(m_namePool), facets);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemacontext.cpp b/src/xmlpatterns/schema/qxsdschemacontext.cpp
new file mode 100644
index 0000000..8e22632
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemacontext.cpp
@@ -0,0 +1,528 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemacontext_p.h"
+
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qxsdschematypesfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaContext::XsdSchemaContext(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+ , m_networkAccessManager(0)
+ , m_uriResolver(0)
+ , m_messageHandler(0)
+{
+}
+
+NamePool::Ptr XsdSchemaContext::namePool() const
+{
+ return m_namePool;
+}
+
+QUrl XsdSchemaContext::baseURI() const
+{
+ return m_baseURI;
+}
+
+void XsdSchemaContext::setBaseURI(const QUrl &uri)
+{
+ m_baseURI = uri;
+}
+
+void XsdSchemaContext::setNetworkAccessManager(QNetworkAccessManager *accessManager)
+{
+ m_networkAccessManager = accessManager;
+}
+
+QNetworkAccessManager* XsdSchemaContext::networkAccessManager() const
+{
+ return m_networkAccessManager;
+}
+
+void XsdSchemaContext::setMessageHandler(QAbstractMessageHandler *handler)
+{
+ m_messageHandler = handler;
+}
+
+QAbstractMessageHandler* XsdSchemaContext::messageHandler() const
+{
+ return m_messageHandler;
+}
+
+QSourceLocation XsdSchemaContext::locationFor(const SourceLocationReflection *const) const
+{
+ return QSourceLocation();
+}
+
+void XsdSchemaContext::setUriResolver(const QAbstractUriResolver *uriResolver)
+{
+ m_uriResolver = uriResolver;
+}
+
+const QAbstractUriResolver* XsdSchemaContext::uriResolver() const
+{
+ return m_uriResolver;
+}
+
+XsdFacet::Hash XsdSchemaContext::facetsForType(const AnySimpleType::Ptr &type) const
+{
+ if (type->isDefinedBySchema())
+ return XsdSimpleType::Ptr(type)->facets();
+ else {
+ if (m_builtinTypesFacetList.isEmpty())
+ m_builtinTypesFacetList = setupBuiltinTypesFacetList();
+
+ return m_builtinTypesFacetList.value(type);
+ }
+}
+
+SchemaTypeFactory::Ptr XsdSchemaContext::schemaTypeFactory() const
+{
+ if (!m_schemaTypeFactory)
+ m_schemaTypeFactory = SchemaTypeFactory::Ptr(new XsdSchemaTypesFactory(m_namePool));
+
+ return m_schemaTypeFactory;
+}
+
+QHash<SchemaType::Ptr, XsdFacet::Hash> XsdSchemaContext::setupBuiltinTypesFacetList() const
+{
+ QHash<SchemaType::Ptr, XsdFacet::Hash> hash;
+
+ const XsdFacet::Ptr fixedCollapseWhiteSpace(new XsdFacet());
+ fixedCollapseWhiteSpace->setType(XsdFacet::WhiteSpace);
+ fixedCollapseWhiteSpace->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse)));
+ fixedCollapseWhiteSpace->setFixed(true);
+
+ const XsdFacet::Ptr collapseWhiteSpace(new XsdFacet());
+ collapseWhiteSpace->setType(XsdFacet::WhiteSpace);
+ collapseWhiteSpace->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse)));
+ collapseWhiteSpace->setFixed(false);
+
+ const XsdFacet::Ptr preserveWhiteSpace(new XsdFacet());
+ preserveWhiteSpace->setType(XsdFacet::WhiteSpace);
+ preserveWhiteSpace->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Preserve)));
+ preserveWhiteSpace->setFixed(false);
+
+ const XsdFacet::Ptr replaceWhiteSpace(new XsdFacet());
+ replaceWhiteSpace->setType(XsdFacet::WhiteSpace);
+ replaceWhiteSpace->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Replace)));
+ replaceWhiteSpace->setFixed(false);
+
+ const XsdFacet::Ptr fixedZeroFractionDigits(new XsdFacet());
+ fixedZeroFractionDigits->setType(XsdFacet::FractionDigits);
+ fixedZeroFractionDigits->setValue(DerivedInteger<TypeNonNegativeInteger>::fromValue(m_namePool, 0));
+ fixedZeroFractionDigits->setFixed(true);
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsString];
+ facets.insert(preserveWhiteSpace->type(), preserveWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsBoolean];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDecimal];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsFloat];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDouble];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDuration];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDateTime];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsTime];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDate];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsGYearMonth];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsGYear];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsGMonthDay];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsGDay];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsGMonth];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsHexBinary];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsBase64Binary];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsAnyURI];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsQName];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNOTATION];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNormalizedString];
+ facets.insert(replaceWhiteSpace->type(), replaceWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsToken];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsLanguage];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+
+ const XsdFacet::Ptr pattern(new XsdFacet());
+ pattern->setType(XsdFacet::Pattern);
+ pattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")));
+ facets.insert(pattern->type(), pattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNMTOKEN];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+
+ const XsdFacet::Ptr pattern(new XsdFacet());
+ pattern->setType(XsdFacet::Pattern);
+ pattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("\\c+")));
+ facets.insert(pattern->type(), pattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsName];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+
+ const XsdFacet::Ptr pattern(new XsdFacet());
+ pattern->setType(XsdFacet::Pattern);
+ pattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("\\i\\c*")));
+ facets.insert(pattern->type(), pattern);
+ }
+
+ const XsdFacet::Ptr ncNamePattern(new XsdFacet());
+ {
+ ncNamePattern->setType(XsdFacet::Pattern);
+ AtomicValue::List patterns;
+ patterns << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("\\i\\c*"));
+ patterns << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("[\\i-[:]][\\c-[:]]*"));
+ ncNamePattern->setMultiValue(patterns);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNCName];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+ facets.insert(ncNamePattern->type(), ncNamePattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsID];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+ facets.insert(ncNamePattern->type(), ncNamePattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsIDREF];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+ facets.insert(ncNamePattern->type(), ncNamePattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsENTITY];
+ facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace);
+ facets.insert(ncNamePattern->type(), ncNamePattern);
+ }
+
+ const XsdFacet::Ptr integerPattern(new XsdFacet());
+ integerPattern->setType(XsdFacet::Pattern);
+ integerPattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("[\\-+]?[0-9]+")));
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsInteger];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNonPositiveInteger];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("0")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNegativeInteger];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("-1")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsLong];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("9223372036854775807")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+
+ const XsdFacet::Ptr minInclusive(new XsdFacet());
+ minInclusive->setType(XsdFacet::MinimumInclusive);
+ minInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("-9223372036854775808")));
+ facets.insert(minInclusive->type(), minInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsInt];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("2147483647")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+
+ const XsdFacet::Ptr minInclusive(new XsdFacet());
+ minInclusive->setType(XsdFacet::MinimumInclusive);
+ minInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("-2147483648")));
+ facets.insert(minInclusive->type(), minInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsShort];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("32767")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+
+ const XsdFacet::Ptr minInclusive(new XsdFacet());
+ minInclusive->setType(XsdFacet::MinimumInclusive);
+ minInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("-32768")));
+ facets.insert(minInclusive->type(), minInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsByte];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("127")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+
+ const XsdFacet::Ptr minInclusive(new XsdFacet());
+ minInclusive->setType(XsdFacet::MinimumInclusive);
+ minInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("-128")));
+ facets.insert(minInclusive->type(), minInclusive);
+ }
+
+ const XsdFacet::Ptr unsignedMinInclusive(new XsdFacet());
+ unsignedMinInclusive->setType(XsdFacet::MinimumInclusive);
+ unsignedMinInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("0")));
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsNonNegativeInteger];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedLong];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("18446744073709551615")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedInt];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("4294967295")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedShort];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("65535")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedByte];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+ facets.insert(integerPattern->type(), integerPattern);
+ facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive);
+
+ const XsdFacet::Ptr maxInclusive(new XsdFacet());
+ maxInclusive->setType(XsdFacet::MaximumInclusive);
+ maxInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("255")));
+ facets.insert(maxInclusive->type(), maxInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsPositiveInteger];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+ facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits);
+
+ const XsdFacet::Ptr minInclusive(new XsdFacet());
+ minInclusive->setType(XsdFacet::MinimumInclusive);
+ minInclusive->setValue(DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("1")));
+ facets.insert(minInclusive->type(), minInclusive);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsYearMonthDuration];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+
+ const XsdFacet::Ptr pattern(new XsdFacet());
+ pattern->setType(XsdFacet::Pattern);
+ pattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("[^DT]*")));
+ facets.insert(pattern->type(), pattern);
+ }
+
+ {
+ XsdFacet::Hash &facets = hash[BuiltinTypes::xsDayTimeDuration];
+ facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace);
+
+ const XsdFacet::Ptr pattern(new XsdFacet());
+ pattern->setType(XsdFacet::Pattern);
+ pattern->setMultiValue(AtomicValue::List() << DerivedString<TypeString>::fromLexical(m_namePool, QString::fromLatin1("[^YM]*(T.*)?")));
+ facets.insert(pattern->type(), pattern);
+ }
+
+ return hash;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemacontext_p.h b/src/xmlpatterns/schema/qxsdschemacontext_p.h
new file mode 100644
index 0000000..6a04ba3
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemacontext_p.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSchemaContext_H
+#define Patternist_XsdSchemaContext_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qreportcontext_p.h"
+#include "qschematypefactory_p.h"
+#include "qxsdschematoken_p.h"
+#include "qxsdschema_p.h"
+#include "qxsdschemachecker_p.h"
+#include "qxsdschemaresolver_p.h"
+
+#include <QtCore/QUrl>
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtXmlPatterns/QAbstractMessageHandler>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A context for schema parsing and validation.
+ *
+ * This class provides the infrastructure for error reporting and
+ * network access. Additionally it stores objects that are used by
+ * both, the parser and the validator.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaContext : public ReportContext
+ {
+ public:
+ /**
+ * A smart pointer wrapping XsdSchemaContext instances.
+ */
+ typedef QExplicitlySharedDataPointer<XsdSchemaContext> Ptr;
+
+ /**
+ * Creates a new schema context object.
+ *
+ * @param namePool The name pool all names belong to.
+ */
+ XsdSchemaContext(const NamePool::Ptr &namePool);
+
+ /**
+ * Returns the name pool of the schema context.
+ */
+ virtual NamePool::Ptr namePool() const;
+
+ /**
+ * Sets the base URI for the main schema.
+ *
+ * The main schema is the one that includes resp. imports
+ * all the other schema files.
+ */
+ virtual void setBaseURI(const QUrl &uri);
+
+ /**
+ * Returns the base URI of the main schema.
+ */
+ virtual QUrl baseURI() const;
+
+ /**
+ * Sets the network access manager that should be used
+ * to access referenced schema definitions.
+ */
+ void setNetworkAccessManager(QNetworkAccessManager *accessManager);
+
+ /**
+ * Returns the network access manager that is used to
+ * access referenced schema definitions.
+ */
+ virtual QNetworkAccessManager* networkAccessManager() const;
+
+ /**
+ * Sets the message @p handler used by the context for error reporting.
+ */
+ void setMessageHandler(QAbstractMessageHandler *handler);
+
+ /**
+ * Returns the message handler used by the context for
+ * error reporting.
+ */
+ virtual QAbstractMessageHandler* messageHandler() const;
+
+ /**
+ * Always returns an empty source location.
+ */
+ virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const;
+
+ /**
+ * Sets the uri @p resolver that is used for resolving URIs in the
+ * schema parser.
+ */
+ void setUriResolver(const QAbstractUriResolver *resolver);
+
+ /**
+ * Returns the uri resolver that is used for resolving URIs in the
+ * schema parser.
+ */
+ virtual const QAbstractUriResolver* uriResolver() const;
+
+ /**
+ * Returns the list of facets for the given simple @p type.
+ */
+ XsdFacet::Hash facetsForType(const AnySimpleType::Ptr &type) const;
+
+ /**
+ * Returns a schema type factory that contains some predefined schema types.
+ */
+ SchemaTypeFactory::Ptr schemaTypeFactory() const;
+
+ /**
+ * The following variables should not be accessed directly.
+ */
+ mutable SchemaTypeFactory::Ptr m_schemaTypeFactory;
+ mutable QHash<SchemaType::Ptr, XsdFacet::Hash> m_builtinTypesFacetList;
+
+ private:
+ QHash<SchemaType::Ptr, XsdFacet::Hash> setupBuiltinTypesFacetList() const;
+
+ NamePool::Ptr m_namePool;
+ QNetworkAccessManager* m_networkAccessManager;
+ QUrl m_baseURI;
+ const QAbstractUriResolver* m_uriResolver;
+ QAbstractMessageHandler* m_messageHandler;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemadebugger.cpp b/src/xmlpatterns/schema/qxsdschemadebugger.cpp
new file mode 100644
index 0000000..8ec7381
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemadebugger.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemadebugger_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaDebugger::XsdSchemaDebugger(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+{
+}
+
+void XsdSchemaDebugger::dumpParticle(const XsdParticle::Ptr &particle, int level)
+{
+ QString prefix; prefix.fill(QLatin1Char(' '), level);
+
+ qDebug("%s min=%s max=%s", qPrintable(prefix), qPrintable(QString::number(particle->minimumOccurs())),
+ qPrintable(particle->maximumOccursUnbounded() ? QLatin1String("unbounded") : QString::number(particle->maximumOccurs())));
+
+ if (particle->term()->isElement()) {
+ qDebug("%selement (%s)", qPrintable(prefix), qPrintable(XsdElement::Ptr(particle->term())->displayName(m_namePool)));
+ } else if (particle->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr group(particle->term());
+ if (group->compositor() == XsdModelGroup::SequenceCompositor) {
+ qDebug("%ssequence", qPrintable(prefix));
+ } else if (group->compositor() == XsdModelGroup::AllCompositor) {
+ qDebug("%sall", qPrintable(prefix));
+ } else if (group->compositor() == XsdModelGroup::ChoiceCompositor) {
+ qDebug("%schoice", qPrintable(prefix));
+ }
+
+ for (int i = 0; i < group->particles().count(); ++i)
+ dumpParticle(group->particles().at(i), level + 5);
+ } else if (particle->term()->isWildcard()) {
+ XsdWildcard::Ptr wildcard(particle->term());
+ qDebug("%swildcard (process=%d)", qPrintable(prefix), wildcard->processContents());
+ }
+}
+
+void XsdSchemaDebugger::dumpInheritance(const SchemaType::Ptr &type, int level)
+{
+ QString prefix; prefix.fill(QLatin1Char(' '), level);
+ qDebug("%s-->%s", qPrintable(prefix), qPrintable(type->displayName(m_namePool)));
+ if (type->wxsSuperType())
+ dumpInheritance(type->wxsSuperType(), ++level);
+}
+
+void XsdSchemaDebugger::dumpWildcard(const XsdWildcard::Ptr &wildcard)
+{
+ QVector<QString> varietyNames;
+ varietyNames.append(QLatin1String("Any"));
+ varietyNames.append(QLatin1String("Enumeration"));
+ varietyNames.append(QLatin1String("Not"));
+
+ QVector<QString> processContentsNames;
+ processContentsNames.append(QLatin1String("Strict"));
+ processContentsNames.append(QLatin1String("Lax"));
+ processContentsNames.append(QLatin1String("Skip"));
+
+ qDebug(" processContents: %s", qPrintable(processContentsNames.at((int)wildcard->processContents())));
+ const XsdWildcard::NamespaceConstraint::Ptr constraint = wildcard->namespaceConstraint();
+ qDebug(" variety: %s", qPrintable(varietyNames.at((int)constraint->variety())));
+ if (constraint->variety() != XsdWildcard::NamespaceConstraint::Any)
+ qDebug() << " namespaces:" << constraint->namespaces();
+}
+
+void XsdSchemaDebugger::dumpType(const SchemaType::Ptr &type)
+{
+ if (type->isComplexType()) {
+ const XsdComplexType::Ptr complexType(type);
+ qDebug("\n+++ Complex Type +++");
+ qDebug("Name: %s (abstract: %s)", qPrintable(complexType->displayName(m_namePool)), complexType->isAbstract() ? "yes" : "no");
+ if (complexType->wxsSuperType())
+ qDebug(" base type: %s", qPrintable(complexType->wxsSuperType()->displayName(m_namePool)));
+ else
+ qDebug(" base type: (none)");
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty)
+ qDebug(" content type: empty");
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple)
+ qDebug(" content type: simple");
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly)
+ qDebug(" content type: element-only");
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed)
+ qDebug(" content type: mixed");
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (complexType->contentType()->simpleType())
+ qDebug(" simple type: %s", qPrintable(complexType->contentType()->simpleType()->displayName(m_namePool)));
+ else
+ qDebug(" simple type: (none)");
+ }
+
+ const XsdAttributeUse::List uses = complexType->attributeUses();
+ qDebug(" %d attributes", uses.count());
+ for (int i = 0; i < uses.count(); ++i) {
+ qDebug(" attr: %s", qPrintable(uses.at(i)->attribute()->displayName(m_namePool)));
+ }
+ qDebug(" has attribute wildcard: %s", complexType->attributeWildcard() ? "yes" : "no");
+ if (complexType->attributeWildcard()) {
+ dumpWildcard(complexType->attributeWildcard());
+ }
+
+ if (complexType->contentType()->particle()) {
+ dumpParticle(complexType->contentType()->particle(), 5);
+ }
+ } else {
+ qDebug("\n+++ Simple Type +++");
+ qDebug("Name: %s", qPrintable(type->displayName(m_namePool)));
+ if (type->isDefinedBySchema()) {
+ const XsdSimpleType::Ptr simpleType(type);
+ if (simpleType->primitiveType())
+ qDebug(" primitive type: %s", qPrintable(simpleType->primitiveType()->displayName(m_namePool)));
+ else
+ qDebug(" primitive type: (none)");
+ }
+ dumpInheritance(type, 0);
+ }
+}
+
+
+void XsdSchemaDebugger::dumpElement(const XsdElement::Ptr &element)
+{
+ QStringList disallowedSubstGroup;
+ if (element->disallowedSubstitutions() & XsdElement::RestrictionConstraint)
+ disallowedSubstGroup << QLatin1String("restriction");
+ if (element->disallowedSubstitutions() & XsdElement::ExtensionConstraint)
+ disallowedSubstGroup << QLatin1String("extension");
+ if (element->disallowedSubstitutions() & XsdElement::SubstitutionConstraint)
+ disallowedSubstGroup << QLatin1String("substitution");
+
+
+ qDebug() << "Name:" << element->displayName(m_namePool);
+ qDebug() << "IsAbstract:" << (element->isAbstract() ? "yes" : "no");
+ qDebug() << "Type:" << element->type()->displayName(m_namePool);
+ qDebug() << "DisallowedSubstitutionGroups:" << disallowedSubstGroup.join(QLatin1String("' "));
+}
+
+void XsdSchemaDebugger::dumpAttribute(const XsdAttribute::Ptr &attribute)
+{
+ qDebug() << "Name:" << attribute->displayName(m_namePool);
+ qDebug() << "Type:" << attribute->type()->displayName(m_namePool);
+}
+
+void XsdSchemaDebugger::dumpSchema(const XsdSchema::Ptr &schema)
+{
+ qDebug() << "------------------------------ Schema -------------------------------";
+
+ // elements
+ {
+ qDebug() << "Global Elements:";
+ const XsdElement::List elements = schema->elements();
+ for (int i = 0; i < elements.count(); ++i) {
+ dumpElement(elements.at(i));
+ }
+ }
+
+ // attributes
+ {
+ qDebug() << "Global Attributes:";
+ const XsdAttribute::List attributes = schema->attributes();
+ for (int i = 0; i < attributes.count(); ++i) {
+ dumpAttribute(attributes.at(i));
+ }
+ }
+
+ // types
+ {
+ qDebug() << "Global Types:";
+ const SchemaType::List types = schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ dumpType(types.at(i));
+ }
+ }
+
+ // anonymous types
+ {
+ qDebug() << "Anonymous Types:";
+ const SchemaType::List types = schema->anonymousTypes();
+ for (int i = 0; i < types.count(); ++i) {
+ dumpType(types.at(i));
+ }
+ }
+
+ qDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemadebugger_p.h b/src/xmlpatterns/schema/qxsdschemadebugger_p.h
new file mode 100644
index 0000000..2225b88
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemadebugger_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSchemaDebugger_H
+#define Patternist_XsdSchemaDebugger_H
+
+#include "qxsdschema_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * A helper class to print out the structure of a compiled schema.
+ */
+ class XsdSchemaDebugger
+ {
+ public:
+ /**
+ * Creates a new schema debugger.
+ *
+ * @param namePool The name pool that the schema uses.
+ */
+ XsdSchemaDebugger(const NamePool::Ptr &namePool);
+
+ /**
+ * Dumps the structure of the given @p particle.
+ *
+ * @param particle The particle to dump.
+ * @param level The level of indention.
+ */
+ void dumpParticle(const XsdParticle::Ptr &particle, int level = 0);
+
+ /**
+ * Dumps the inheritance path of the given @p type.
+ *
+ * @param type The type to dump.
+ * @param level The level of indention.
+ */
+ void dumpInheritance(const SchemaType::Ptr &type, int level = 0);
+
+ /**
+ * Dumps the structure of the given @p wildcard.
+ */
+ void dumpWildcard(const XsdWildcard::Ptr &wildcard);
+
+ /**
+ * Dumps the structure of the given @p type.
+ */
+ void dumpType(const SchemaType::Ptr &type);
+
+ /**
+ * Dumps the structure of the given @p element.
+ */
+ void dumpElement(const XsdElement::Ptr &element);
+
+ /**
+ * Dumps the structure of the given @p attribute.
+ */
+ void dumpAttribute(const XsdAttribute::Ptr &attribute);
+
+ /**
+ * Dumps the structure of the complete @p schema.
+ */
+ void dumpSchema(const XsdSchema::Ptr &schema);
+
+ private:
+ const NamePool::Ptr m_namePool;
+ };
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemahelper.cpp b/src/xmlpatterns/schema/qxsdschemahelper.cpp
new file mode 100644
index 0000000..7813808
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemahelper.cpp
@@ -0,0 +1,821 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemahelper_p.h"
+
+#include "qbuiltintypes_p.h"
+#include "qvaluefactory_p.h"
+#include "qxsdcomplextype_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdsimpletype_p.h"
+#include "qxsdtypechecker_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/*
+ * Calculates the effective total range minimum of the given @p particle as
+ * described by the algorithm in the schema spec.
+ */
+static inline unsigned int effectiveTotalRangeMinimum(const XsdParticle::Ptr &particle)
+{
+ const XsdModelGroup::Ptr group = particle->term();
+
+ if (group->compositor() == XsdModelGroup::ChoiceCompositor) {
+ // @see http://www.w3.org/TR/xmlschema11-1/# cos-choice-range
+
+ int minValue = -1;
+
+ const XsdParticle::List particles = group->particles();
+ if (particles.isEmpty())
+ minValue = 0;
+
+ for (int i = 0; i < particles.count(); ++i) {
+ const XsdParticle::Ptr particle = particles.at(i);
+
+ if (particle->term()->isElement() || particle->term()->isWildcard()) {
+ if (minValue == -1) {
+ minValue = particle->minimumOccurs();
+ } else {
+ minValue = qMin((unsigned int)minValue, particle->minimumOccurs());
+ }
+ } else if (particle->term()->isModelGroup()) {
+ if (minValue == -1) {
+ minValue = effectiveTotalRangeMinimum(particle);
+ } else {
+ minValue = qMin((unsigned int)minValue, effectiveTotalRangeMinimum(particle));
+ }
+ }
+ }
+
+ return (particle->minimumOccurs() * minValue);
+
+ } else {
+ // @see http://www.w3.org/TR/xmlschema11-1/# cos-seq-range
+
+ unsigned int sum = 0;
+ const XsdParticle::List particles = group->particles();
+ for (int i = 0; i < particles.count(); ++i) {
+ const XsdParticle::Ptr particle = particles.at(i);
+
+ if (particle->term()->isElement() || particle->term()->isWildcard())
+ sum += particle->minimumOccurs();
+ else if (particle->term()->isModelGroup())
+ sum += effectiveTotalRangeMinimum(particle);
+ }
+
+ return (particle->minimumOccurs() * sum);
+ }
+}
+
+bool XsdSchemaHelper::isParticleEmptiable(const XsdParticle::Ptr &particle)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-group-emptiable
+
+ if (particle->minimumOccurs() == 0)
+ return true;
+
+ if (!(particle->term()->isModelGroup()))
+ return false;
+
+ return (effectiveTotalRangeMinimum(particle) == 0);
+}
+
+bool XsdSchemaHelper::wildcardAllowsNamespaceName(const QString &nameSpace, const XsdWildcard::NamespaceConstraint::Ptr &constraint)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-wildcard-namespace
+
+ // 1
+ if (constraint->variety() == XsdWildcard::NamespaceConstraint::Any)
+ return true;
+
+ // 2
+ if (constraint->variety() == XsdWildcard::NamespaceConstraint::Not) { // 2.1
+ if (!constraint->namespaces().contains(nameSpace)) // 2.2
+ if (nameSpace != XsdWildcard::absentNamespace()) // 2.3
+ return true;
+ }
+
+ // 3
+ if (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) {
+ if (constraint->namespaces().contains(nameSpace))
+ return true;
+ }
+
+ return false;
+}
+
+bool XsdSchemaHelper::wildcardAllowsExpandedName(const QXmlName &name, const XsdWildcard::Ptr &wildcard, const NamePool::Ptr &namePool)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-wildcard-name
+
+ // 1
+ if (!wildcardAllowsNamespaceName(namePool->stringForNamespace(name.namespaceURI()), wildcard->namespaceConstraint()))
+ return false;
+
+ // 2, 3, 4
+ //TODO: we have no disallowed namespace yet
+
+ return true;
+}
+
+// small helper function that should be available in Qt 4.6
+template<class T>
+static inline bool containsSet(const QSet<T> &super, const QSet<T> &sub)
+{
+ QSetIterator<T> it(sub);
+ while (it.hasNext()) {
+ if (!super.contains(it.next()))
+ return false;
+ }
+
+ return true;
+}
+
+bool XsdSchemaHelper::isWildcardSubset(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-ns-subset
+ // wildcard =^ sub
+ // otherWildcard =^ super
+
+ const XsdWildcard::NamespaceConstraint::Ptr constraint(wildcard->namespaceConstraint());
+ const XsdWildcard::NamespaceConstraint::Ptr otherConstraint(otherWildcard->namespaceConstraint());
+
+ // 1
+ if (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Any)
+ return true;
+
+ // 2
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+ if (containsSet<QString>(otherConstraint->namespaces(), constraint->namespaces()))
+ return true;
+ }
+
+ // 3
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) {
+ if (constraint->namespaces().intersect(otherConstraint->namespaces()).isEmpty())
+ return true;
+ }
+
+ // 4
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) {
+ if (containsSet<QString>(constraint->namespaces(), otherConstraint->namespaces()))
+ return true;
+ }
+
+ return false;
+}
+
+XsdWildcard::Ptr XsdSchemaHelper::wildcardUnion(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-aw-union
+
+ XsdWildcard::Ptr unionWildcard(new XsdWildcard());
+
+ const XsdWildcard::NamespaceConstraint::Ptr constraint(wildcard->namespaceConstraint());
+ const XsdWildcard::NamespaceConstraint::Ptr otherConstraint(otherWildcard->namespaceConstraint());
+
+ // 1
+ if ((constraint->variety() == otherConstraint->variety()) &&
+ (constraint->namespaces() == otherConstraint->namespaces())) {
+ unionWildcard->namespaceConstraint()->setVariety(constraint->variety());
+ unionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces());
+ return unionWildcard;
+ }
+
+ // 2
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Any) || (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Any)) {
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ return unionWildcard;
+ }
+
+ // 3
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ unionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces() + otherConstraint->namespaces());
+ return unionWildcard;
+ }
+
+ // 4
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) {
+ if (constraint->namespaces() != otherConstraint->namespaces()) {
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ unionWildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
+ return unionWildcard;
+ }
+ }
+
+ // 5
+ QSet<QString> sSet, negatedSet;
+ bool matches5 = false;
+ if (((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && !constraint->namespaces().contains(XsdWildcard::absentNamespace()))
+ && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ negatedSet = constraint->namespaces();
+ sSet = otherConstraint->namespaces();
+ matches5 = true;
+ } else if (((otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not) && !otherConstraint->namespaces().contains(XsdWildcard::absentNamespace()))
+ && (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ negatedSet = otherConstraint->namespaces();
+ sSet = constraint->namespaces();
+ matches5 = true;
+ }
+
+ if (matches5) {
+ if (sSet.contains(negatedSet.values().first()) && sSet.contains(XsdWildcard::absentNamespace())) { // 5.1
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ return unionWildcard;
+ }
+ if (sSet.contains(negatedSet.values().first()) && !sSet.contains(XsdWildcard::absentNamespace())) { // 5.2
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ unionWildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
+ return unionWildcard;
+ }
+ if (!sSet.contains(negatedSet.values().first()) && sSet.contains(XsdWildcard::absentNamespace())) { // 5.3
+ return XsdWildcard::Ptr(); // not expressible
+ }
+ if (!sSet.contains(negatedSet.values().first()) && !sSet.contains(XsdWildcard::absentNamespace())) { // 5.4
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ unionWildcard->namespaceConstraint()->setNamespaces(negatedSet);
+ return unionWildcard;
+ }
+ }
+
+ // 6
+ bool matches6 = false;
+ if (((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && constraint->namespaces().contains(XsdWildcard::absentNamespace()))
+ && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ negatedSet = constraint->namespaces();
+ sSet = otherConstraint->namespaces();
+ matches6 = true;
+ } else if (((otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not) && otherConstraint->namespaces().contains(XsdWildcard::absentNamespace()))
+ && (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ negatedSet = otherConstraint->namespaces();
+ sSet = constraint->namespaces();
+ matches6 = true;
+ }
+
+ if (matches6) {
+ if (sSet.contains(XsdWildcard::absentNamespace())) { // 6.1
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ return unionWildcard;
+ }
+ if (!sSet.contains(XsdWildcard::absentNamespace())) { // 6.2
+ unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ unionWildcard->namespaceConstraint()->setNamespaces(QSet<QString>() += XsdWildcard::absentNamespace());
+ return unionWildcard;
+ }
+ }
+
+ return XsdWildcard::Ptr();
+}
+
+XsdWildcard::Ptr XsdSchemaHelper::wildcardIntersection(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-aw-intersect
+
+ const XsdWildcard::NamespaceConstraint::Ptr constraint(wildcard->namespaceConstraint());
+ const XsdWildcard::NamespaceConstraint::Ptr otherConstraint(otherWildcard->namespaceConstraint());
+
+ const XsdWildcard::Ptr intersectionWildcard(new XsdWildcard());
+
+ // 1
+ if ((constraint->variety() == otherConstraint->variety()) &&
+ (constraint->namespaces() == otherConstraint->namespaces())) {
+ intersectionWildcard->namespaceConstraint()->setVariety(constraint->variety());
+ intersectionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces());
+ return intersectionWildcard;
+ }
+
+ // 2
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Any) &&
+ (otherConstraint->variety() != XsdWildcard::NamespaceConstraint::Any)) {
+ intersectionWildcard->namespaceConstraint()->setVariety(otherConstraint->variety());
+ intersectionWildcard->namespaceConstraint()->setNamespaces(otherConstraint->namespaces());
+ return intersectionWildcard;
+ }
+
+ // 2
+ if ((constraint->variety() != XsdWildcard::NamespaceConstraint::Any) &&
+ (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Any)) {
+ intersectionWildcard->namespaceConstraint()->setVariety(constraint->variety());
+ intersectionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces());
+ return intersectionWildcard;
+ }
+
+ // 3
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) &&
+ (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ QSet<QString> set = otherConstraint->namespaces();
+ set.subtract(constraint->namespaces());
+ set.remove(XsdWildcard::absentNamespace());
+
+ intersectionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ intersectionWildcard->namespaceConstraint()->setNamespaces(set);
+
+ return intersectionWildcard;
+ }
+
+ // 3
+ if ((otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not) &&
+ (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ QSet<QString> set = constraint->namespaces();
+ set.subtract(otherConstraint->namespaces());
+ set.remove(XsdWildcard::absentNamespace());
+
+ intersectionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ intersectionWildcard->namespaceConstraint()->setNamespaces(set);
+
+ return intersectionWildcard;
+ }
+
+ // 4
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) &&
+ (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) {
+
+ QSet<QString> set = constraint->namespaces();
+ set.intersect(otherConstraint->namespaces());
+
+ intersectionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ intersectionWildcard->namespaceConstraint()->setNamespaces(set);
+
+ return intersectionWildcard;
+ }
+
+ // 6
+ if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) &&
+ (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) {
+ if (!(constraint->namespaces().contains(XsdWildcard::absentNamespace())) && otherConstraint->namespaces().contains(XsdWildcard::absentNamespace())) {
+ return wildcard;
+ }
+ if (constraint->namespaces().contains(XsdWildcard::absentNamespace()) && !(otherConstraint->namespaces().contains(XsdWildcard::absentNamespace()))) {
+ return otherWildcard;
+ }
+ }
+
+ // 5 as not expressible return empty wildcard
+ return XsdWildcard::Ptr();
+}
+
+static SchemaType::DerivationConstraints convertBlockingConstraints(const NamedSchemaComponent::BlockingConstraints &constraints)
+{
+ SchemaType::DerivationConstraints result = 0;
+
+ if (constraints & NamedSchemaComponent::RestrictionConstraint)
+ result |= SchemaType::RestrictionConstraint;
+ if (constraints & NamedSchemaComponent::ExtensionConstraint)
+ result |= SchemaType::ExtensionConstraint;
+
+ return result;
+}
+
+bool XsdSchemaHelper::isValidlySubstitutable(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, const SchemaType::DerivationConstraints &constraints)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#key-val-sub-type
+
+ // 1
+ if (type->isComplexType() && otherType->isComplexType()) {
+ SchemaType::DerivationConstraints keywords = constraints;
+ if (otherType->isDefinedBySchema())
+ keywords |= convertBlockingConstraints(XsdComplexType::Ptr(otherType)->prohibitedSubstitutions());
+
+ return isComplexDerivationOk(type, otherType, keywords);
+ }
+
+ // 2
+ if (type->isComplexType() && otherType->isSimpleType()) {
+ return isComplexDerivationOk(type, otherType, constraints);
+ }
+
+ // 3
+ if (type->isSimpleType() && otherType->isSimpleType()) {
+ return isSimpleDerivationOk(type, otherType, constraints);
+ }
+
+ return false;
+}
+
+bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-st-derived-ok
+
+ // 1
+ if (derivedType == baseType)
+ return true;
+
+ // 2.1
+ if ((constraints & SchemaType::RestrictionConstraint) || derivedType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) {
+ return false;
+ }
+
+ // 2.2.1
+ if (derivedType->wxsSuperType() == baseType)
+ return true;
+
+ // 2.2.2
+ if (derivedType->wxsSuperType() != BuiltinTypes::xsAnyType) {
+ if (isSimpleDerivationOk(derivedType->wxsSuperType(), baseType, constraints))
+ return true;
+ }
+
+ // 2.2.3
+ if (derivedType->category() == SchemaType::SimpleTypeList || derivedType->category() == SchemaType::SimpleTypeUnion) {
+ if (baseType == BuiltinTypes::xsAnySimpleType)
+ return true;
+ }
+
+ // 2.2.4
+ if (baseType->category() == SchemaType::SimpleTypeUnion && baseType->isDefinedBySchema()) { // 2.2.4.1
+ const AnySimpleType::List memberTypes = XsdSimpleType::Ptr(baseType)->memberTypes();
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ if (isSimpleDerivationOk(derivedType, memberTypes.at(i), constraints)) { // 2.2.4.2
+ if (XsdSimpleType::Ptr(baseType)->facets().isEmpty()) { // 2.2.4.3
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool XsdSchemaHelper::isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints)
+{
+ if (!derivedType)
+ return false;
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-derived-ok
+
+ // 1
+ if (derivedType != baseType) {
+ if ((derivedType->derivationMethod() == SchemaType::DerivationRestriction) && (constraints & SchemaType::RestrictionConstraint))
+ return false;
+ if ((derivedType->derivationMethod() == SchemaType::DerivationExtension) && (constraints & SchemaType::ExtensionConstraint))
+ return false;
+ }
+
+ // 2.1
+ if (derivedType == baseType)
+ return true;
+
+ // 2.2
+ if (derivedType->wxsSuperType() == baseType)
+ return true;
+
+ // 2.3
+ bool isOk = true;
+ if (derivedType->wxsSuperType() == BuiltinTypes::xsAnyType) { // 2.3.1
+ isOk = false;
+ } else { // 2.3.2
+ if (!derivedType->wxsSuperType())
+ return false;
+
+ if (derivedType->wxsSuperType()->isComplexType()) { // 2.3.2.1
+ isOk = isComplexDerivationOk(derivedType->wxsSuperType(), baseType, constraints);
+ } else { // 2.3.2.2
+ isOk = isSimpleDerivationOk(derivedType->wxsSuperType(), baseType, constraints);
+ }
+ }
+ if (isOk)
+ return true;
+
+ return false;
+}
+
+bool XsdSchemaHelper::constructAndCompare(const DerivedString<TypeString>::Ptr &operand1,
+ const AtomicComparator::Operator op,
+ const DerivedString<TypeString>::Ptr &operand2,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const sourceLocationReflection)
+{
+ Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO,
+ "We can only compare atomic values.");
+
+ // we can not cast a xs:String to a xs:QName, so lets go the safe way
+ if (type->name(context->namePool()) == BuiltinTypes::xsQName->name(context->namePool()))
+ return false;
+
+ const AtomicValue::Ptr value1 = ValueFactory::fromLexical(operand1->stringValue(), type, context, sourceLocationReflection);
+ if (value1->hasError())
+ return false;
+
+ const AtomicValue::Ptr value2 = ValueFactory::fromLexical(operand2->stringValue(), type, context, sourceLocationReflection);
+ if (value2->hasError())
+ return false;
+
+ return ComparisonFactory::compare(value1, op, value2, type, context, sourceLocationReflection);
+}
+
+bool XsdSchemaHelper::checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, const XsdWildcard::Ptr &derivedWildcard)
+{
+ if (baseWildcard->processContents() == XsdWildcard::Strict) {
+ if (derivedWildcard->processContents() == XsdWildcard::Lax || derivedWildcard->processContents() == XsdWildcard::Skip) {
+ return false;
+ }
+ } else if (baseWildcard->processContents() == XsdWildcard::Lax) {
+ if (derivedWildcard->processContents() == XsdWildcard::Skip)
+ return false;
+ }
+
+ return true;
+}
+
+bool XsdSchemaHelper::foundSubstitutionGroupTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, QSet<XsdElement::Ptr> &visitedElements)
+{
+ if (visitedElements.contains(member))
+ return false;
+ else
+ visitedElements.insert(member);
+
+ if (member->substitutionGroupAffiliations().isEmpty())
+ return false;
+
+ if (member->substitutionGroupAffiliations().contains(head)) {
+ return true;
+ } else {
+ const XsdElement::List affiliations = member->substitutionGroupAffiliations();
+ for (int i = 0; i < affiliations.count(); ++i) {
+ if (foundSubstitutionGroupTransitive(head, affiliations.at(i), visitedElements))
+ return true;
+ }
+
+ return false;
+ }
+}
+
+void XsdSchemaHelper::foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType, const SchemaType::Ptr &memberType,
+ QSet<SchemaType::DerivationMethod> &derivationSet, NamedSchemaComponent::BlockingConstraints &blockSet)
+{
+ if (!memberType)
+ return;
+
+ if (memberType == headType)
+ return;
+
+ derivationSet.insert(memberType->derivationMethod());
+
+ if (memberType->isComplexType()) {
+ const XsdComplexType::Ptr complexType(memberType);
+ blockSet |= complexType->prohibitedSubstitutions();
+ }
+
+ foundSubstitutionGroupTypeInheritance(headType, memberType->wxsSuperType(), derivationSet, blockSet);
+}
+
+bool XsdSchemaHelper::substitutionGroupOkTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, const NamePool::Ptr &namePool)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-equiv-derived-ok-rec
+
+ // 1
+ if ((member->name(namePool) == head->name(namePool)) && (member->type() == head->type()))
+ return true;
+
+ // 2.1
+ if (head->disallowedSubstitutions() & NamedSchemaComponent::SubstitutionConstraint)
+ return false;
+
+ // 2.2
+ {
+ QSet<XsdElement::Ptr> visitedElements;
+ if (!foundSubstitutionGroupTransitive(head, member, visitedElements))
+ return false;
+ }
+
+ // 2.3
+ {
+ QSet<SchemaType::DerivationMethod> derivationSet;
+ NamedSchemaComponent::BlockingConstraints blockSet;
+
+ foundSubstitutionGroupTypeInheritance(head->type(), member->type(), derivationSet, blockSet);
+
+ NamedSchemaComponent::BlockingConstraints checkSet(blockSet);
+ checkSet |= head->disallowedSubstitutions();
+ if (head->type()->isComplexType()) {
+ const XsdComplexType::Ptr complexType(head->type());
+ checkSet |= complexType->prohibitedSubstitutions();
+ }
+
+ if ((checkSet & NamedSchemaComponent::RestrictionConstraint) && derivationSet.contains(SchemaType::DerivationRestriction))
+ return false;
+ if ((checkSet & NamedSchemaComponent::ExtensionConstraint) && derivationSet.contains(SchemaType::DerivationExtension))
+ return false;
+ if (checkSet & NamedSchemaComponent::SubstitutionConstraint)
+ return false;
+ }
+
+ return true;
+}
+
+bool XsdSchemaHelper::isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup, const XsdAttributeGroup::Ptr &attributeGroup, const XsdSchemaContext::Ptr &context, QString &errorMsg)
+{
+ // @see http://www.w3.org/TR/xmlschema-1/#derivation-ok-restriction
+
+ const XsdAttributeUse::List derivedAttributeUses = derivedAttributeGroup->attributeUses();
+ const XsdAttributeUse::List baseAttributeUses = attributeGroup->attributeUses();
+
+ return isValidAttributeUsesRestriction(derivedAttributeUses, baseAttributeUses,
+ derivedAttributeGroup->wildcard(), attributeGroup->wildcard(), context, errorMsg);
+}
+
+bool XsdSchemaHelper::isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &baseAttributeUses,
+ const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg)
+{
+ const NamePool::Ptr namePool(context->namePool());
+
+ QHash<QXmlName, XsdAttributeUse::Ptr> baseAttributeUsesLookup;
+ for (int i = 0; i < baseAttributeUses.count(); ++i)
+ baseAttributeUsesLookup.insert(baseAttributeUses.at(i)->attribute()->name(namePool), baseAttributeUses.at(i));
+
+ QHash<QXmlName, XsdAttributeUse::Ptr> derivedAttributeUsesLookup;
+ for (int i = 0; i < derivedAttributeUses.count(); ++i)
+ derivedAttributeUsesLookup.insert(derivedAttributeUses.at(i)->attribute()->name(namePool), derivedAttributeUses.at(i));
+
+ // 2
+ for (int i = 0; i < derivedAttributeUses.count(); ++i) {
+ const XsdAttributeUse::Ptr derivedAttributeUse = derivedAttributeUses.at(i);
+
+ // prohibited attributes are no real attributes, so skip them in that test here
+ if (derivedAttributeUse->useType() == XsdAttributeUse::ProhibitedUse)
+ continue;
+
+ if (baseAttributeUsesLookup.contains(derivedAttributeUse->attribute()->name(namePool))) {
+ const XsdAttributeUse::Ptr baseAttributeUse(baseAttributeUsesLookup.value(derivedAttributeUse->attribute()->name(namePool)));
+
+ // 2.1.1
+ if (baseAttributeUse->isRequired() == true && derivedAttributeUse->isRequired() == false) {
+ errorMsg = QtXmlPatterns::tr("Base attribute %1 is required but derived attribute is not.").arg(formatAttribute(baseAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+
+ // 2.1.2
+ if (!isSimpleDerivationOk(derivedAttributeUse->attribute()->type(), baseAttributeUse->attribute()->type(), SchemaType::DerivationConstraints())) {
+ errorMsg = QtXmlPatterns::tr("Type of derived attribute %1 cannot be validly derived from type of base attribute.").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+
+ // 2.1.3
+ XsdAttributeUse::ValueConstraint::Ptr derivedConstraint;
+ if (derivedAttributeUse->valueConstraint())
+ derivedConstraint = derivedAttributeUse->valueConstraint();
+ else if (derivedAttributeUse->attribute()->valueConstraint())
+ derivedConstraint = XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(derivedAttributeUse->attribute()->valueConstraint());
+
+ XsdAttributeUse::ValueConstraint::Ptr baseConstraint;
+ if (baseAttributeUse->valueConstraint())
+ baseConstraint = baseAttributeUse->valueConstraint();
+ else if (baseAttributeUse->attribute()->valueConstraint())
+ baseConstraint = XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(baseAttributeUse->attribute()->valueConstraint());
+
+ bool ok = false;
+ if (!baseConstraint || baseConstraint->variety() == XsdAttributeUse::ValueConstraint::Default)
+ ok = true;
+
+ if (derivedConstraint && baseConstraint) {
+ const XsdTypeChecker checker(context, QVector<QXmlName>(), QSourceLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1));
+ if (derivedConstraint->variety() == XsdAttributeUse::ValueConstraint::Fixed && checker.valuesAreEqual(derivedConstraint->value(), baseConstraint->value(), baseAttributeUse->attribute()->type()))
+ ok = true;
+ }
+
+ if (!ok) {
+ errorMsg = QtXmlPatterns::tr("Value constraint of derived attribute %1 does not match value constraint of base attribute.").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+ } else {
+ if (!wildcard) {
+ errorMsg = QtXmlPatterns::tr("Derived attribute %1 does not exist in the base definition.").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+
+ QXmlName name = derivedAttributeUse->attribute()->name(namePool);
+
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ if (name.namespaceURI() == StandardNamespaces::empty)
+ name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+
+ if (!wildcardAllowsExpandedName(name, wildcard, namePool)) {
+ errorMsg = QtXmlPatterns::tr("Derived attribute %1 does not match the wildcard in the base definition.").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+ }
+ }
+
+ // 3
+ for (int i = 0; i < baseAttributeUses.count(); ++i) {
+ const XsdAttributeUse::Ptr baseAttributeUse = baseAttributeUses.at(i);
+
+ if (baseAttributeUse->isRequired()) {
+ if (derivedAttributeUsesLookup.contains(baseAttributeUse->attribute()->name(namePool))) {
+ if (!derivedAttributeUsesLookup.value(baseAttributeUse->attribute()->name(namePool))->isRequired()) {
+ errorMsg = QtXmlPatterns::tr("Base attribute %1 is required but derived attribute is not.").arg(formatAttribute(baseAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+ } else {
+ errorMsg = QtXmlPatterns::tr("Base attribute %1 is required but missing in derived definition.").arg(formatAttribute(baseAttributeUse->attribute()->displayName(namePool)));
+ return false;
+ }
+ }
+ }
+
+ // 4
+ if (derivedWildcard) {
+ if (!wildcard) {
+ errorMsg = QtXmlPatterns::tr("Derived definition contains an %1 element that does not exists in the base definition").arg(formatElement("anyAttribute."));
+ return false;
+ }
+
+ if (!isWildcardSubset(derivedWildcard, wildcard)) {
+ errorMsg = QtXmlPatterns::tr("Derived wildcard is not a subset of the base wildcard.");
+ return false;
+ }
+
+ if (!checkWildcardProcessContents(wildcard, derivedWildcard)) {
+ errorMsg = QtXmlPatterns::tr("%1 of derived wildcard is not a valid restriction of %2 of base wildcard").arg(formatKeyword("processContents")).arg(formatKeyword("processContents."));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool XsdSchemaHelper::isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses,
+ const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-extends
+
+ const NamePool::Ptr namePool(context->namePool());
+
+ // 1.2
+ QHash<QXmlName, XsdAttribute::Ptr> lookupHash;
+ for (int i = 0; i < derivedAttributeUses.count(); ++i)
+ lookupHash.insert(derivedAttributeUses.at(i)->attribute()->name(namePool), derivedAttributeUses.at(i)->attribute());
+
+ for (int i = 0; i < attributeUses.count(); ++i) {
+ const QXmlName attributeName = attributeUses.at(i)->attribute()->name(namePool);
+ if (!lookupHash.contains(attributeName)) {
+ errorMsg = QtXmlPatterns::tr("Attribute %1 from base type is missing in derived type.").arg(formatKeyword(namePool->displayName(attributeName)));
+ return false;
+ }
+
+ if (lookupHash.value(attributeName)->type() != attributeUses.at(i)->attribute()->type()) {
+ errorMsg = QtXmlPatterns::tr("Type of derived attribute %1 differs from type of base attribute.").arg(formatKeyword(namePool->displayName(attributeName)));
+ return false;
+ }
+ }
+
+ // 1.3
+ if (wildcard) {
+ if (!derivedWildcard) {
+ errorMsg = QtXmlPatterns::tr("Base definition contains an %1 element that is missing in the derived definition").arg(formatElement("anyAttribute."));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemahelper_p.h b/src/xmlpatterns/schema/qxsdschemahelper_p.h
new file mode 100644
index 0000000..410b224
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemahelper_p.h
@@ -0,0 +1,217 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSchemaHelper_H
+#define Patternist_XsdSchemaHelper_H
+
+#include "qcomparisonfactory_p.h"
+#include "qschematype_p.h"
+#include "qxsdattributegroup_p.h"
+#include "qxsdelement_p.h"
+#include "qxsdparticle_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdwildcard_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Contains helper methods that are used by XsdSchemaParser, XsdSchemaResolver and XsdSchemaChecker.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaHelper
+ {
+ public:
+ /**
+ * Checks whether the given @p particle is emptiable as defined by the
+ * algorithm in the schema spec.
+ */
+ static bool isParticleEmptiable(const XsdParticle::Ptr &particle);
+
+ /**
+ * Checks whether the given @p nameSpace is allowed by the given namespace @p constraint.
+ */
+ static bool wildcardAllowsNamespaceName(const QString &nameSpace,
+ const XsdWildcard::NamespaceConstraint::Ptr &constraint);
+
+ /**
+ * Checks whether the given @p name is allowed by the namespace constraint of the given @p wildcard.
+ */
+ static bool wildcardAllowsExpandedName(const QXmlName &name,
+ const XsdWildcard::Ptr &wildcard,
+ const NamePool::Ptr &namePool);
+
+ /**
+ * Checks whether the @p wildcard is a subset of @p otherWildcard.
+ */
+ static bool isWildcardSubset(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard);
+
+ /**
+ * Returns the union of the given @p wildcard and @p otherWildcard.
+ */
+ static XsdWildcard::Ptr wildcardUnion(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard);
+
+ /**
+ * Returns the intersection of the given @p wildcard and @p otherWildcard.
+ */
+ static XsdWildcard::Ptr wildcardIntersection(const XsdWildcard::Ptr &wildcard,
+ const XsdWildcard::Ptr &otherWildcard);
+
+ /**
+ * Returns whether the given @p type is validly substitutable for an @p otherType
+ * under the given @p constraints.
+ */
+ static bool isValidlySubstitutable(const SchemaType::Ptr &type,
+ const SchemaType::Ptr &otherType,
+ const SchemaType::DerivationConstraints &constraints);
+
+ /**
+ * Returns whether the simple @p derivedType can be derived from the simple @p baseType
+ * under the given @p constraints.
+ */
+ static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType,
+ const SchemaType::Ptr &baseType,
+ const SchemaType::DerivationConstraints &constraints);
+
+ /**
+ * Returns whether the complex @p derivedType can be derived from the complex @p baseType
+ * under the given @p constraints.
+ */
+ static bool isComplexDerivationOk(const SchemaType::Ptr &derivedType,
+ const SchemaType::Ptr &baseType,
+ const SchemaType::DerivationConstraints &constraints);
+
+ /**
+ * This method takes the two string based operands @p operand1 and @p operand2 and converts them to instances of type @p type.
+ * If the conversion fails, @c false is returned, otherwise the instances are compared by the given operator @p op and the
+ * result of the comparison is returned.
+ */
+ static bool constructAndCompare(const DerivedString<TypeString>::Ptr &operand1,
+ const AtomicComparator::Operator op,
+ const DerivedString<TypeString>::Ptr &operand2,
+ const SchemaType::Ptr &type,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const sourceLocationReflection);
+
+ /**
+ * Returns whether the process content property of the @p derivedWildcard is valid
+ * according to the process content property of its @p baseWildcard.
+ */
+ static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard,
+ const XsdWildcard::Ptr &derivedWildcard);
+
+ /**
+ * Checks whether @[ member is a member of the substitution group with the given @p head.
+ */
+ static bool foundSubstitutionGroupTransitive(const XsdElement::Ptr &head,
+ const XsdElement::Ptr &member,
+ QSet<XsdElement::Ptr> &visitedElements);
+
+ /**
+ * A helper method that iterates over the type hierarchy from @p memberType up to @p headType and collects all
+ * @p derivationSet and @p blockSet constraints that exists on the way there.
+ */
+ static void foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType,
+ const SchemaType::Ptr &memberType,
+ QSet<SchemaType::DerivationMethod> &derivationSet,
+ NamedSchemaComponent::BlockingConstraints &blockSet);
+
+ /**
+ * Checks if the @p member is transitive to @p head.
+ */
+ static bool substitutionGroupOkTransitive(const XsdElement::Ptr &head,
+ const XsdElement::Ptr &member,
+ const NamePool::Ptr &namePool);
+
+ /**
+ * Checks if @p derivedAttributeGroup is a valid restriction for @p attributeGroup.
+ */
+ static bool isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup,
+ const XsdAttributeGroup::Ptr &attributeGroup,
+ const XsdSchemaContext::Ptr &context,
+ QString &errorMsg);
+
+ /**
+ * Checks if @p derivedAttributeUses are a valid restriction for @p attributeUses.
+ */
+ static bool isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses,
+ const XsdAttributeUse::List &attributeUses,
+ const XsdWildcard::Ptr &derivedWildcard,
+ const XsdWildcard::Ptr &wildcard,
+ const XsdSchemaContext::Ptr &context,
+ QString &errorMsg);
+
+ /**
+ * Checks if @p derivedAttributeUses are a valid extension for @p attributeUses.
+ */
+ static bool isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses,
+ const XsdAttributeUse::List &attributeUses,
+ const XsdWildcard::Ptr &derivedWildcard,
+ const XsdWildcard::Ptr &wildcard,
+ const XsdSchemaContext::Ptr &context,
+ QString &errorMsg);
+
+ private:
+ Q_DISABLE_COPY(XsdSchemaHelper)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemamerger.cpp b/src/xmlpatterns/schema/qxsdschemamerger.cpp
new file mode 100644
index 0000000..4ffcea3
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemamerger.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemamerger_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaMerger::XsdSchemaMerger(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema)
+{
+ merge(schema, otherSchema);
+}
+
+XsdSchema::Ptr XsdSchemaMerger::mergedSchema() const
+{
+ return m_mergedSchema;
+}
+
+void XsdSchemaMerger::merge(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema)
+{
+ m_mergedSchema = XsdSchema::Ptr(new XsdSchema(otherSchema->namePool()));
+
+ // first fill the merged schema with the values from schema
+ if (schema) {
+ const XsdElement::List elements = schema->elements();
+ for (int i = 0; i < elements.count(); ++i) {
+ m_mergedSchema->addElement(elements.at(i));
+ }
+
+ const XsdAttribute::List attributes = schema->attributes();
+ for (int i = 0; i < attributes.count(); ++i) {
+ m_mergedSchema->addAttribute(attributes.at(i));
+ }
+
+ const SchemaType::List types = schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ m_mergedSchema->addType(types.at(i));
+ }
+
+ const SchemaType::List anonymousTypes = schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ m_mergedSchema->addAnonymousType(anonymousTypes.at(i));
+ }
+
+ const XsdModelGroup::List elementGroups = schema->elementGroups();
+ for (int i = 0; i < elementGroups.count(); ++i) {
+ m_mergedSchema->addElementGroup(elementGroups.at(i));
+ }
+
+ const XsdAttributeGroup::List attributeGroups = schema->attributeGroups();
+ for (int i = 0; i < attributeGroups.count(); ++i) {
+ m_mergedSchema->addAttributeGroup(attributeGroups.at(i));
+ }
+
+ const XsdNotation::List notations = schema->notations();
+ for (int i = 0; i < notations.count(); ++i) {
+ m_mergedSchema->addNotation(notations.at(i));
+ }
+
+ const XsdIdentityConstraint::List identityConstraints = schema->identityConstraints();
+ for (int i = 0; i < identityConstraints.count(); ++i) {
+ m_mergedSchema->addIdentityConstraint(identityConstraints.at(i));
+ }
+ }
+
+ // then merge in the values from the otherSchema
+ {
+ const XsdElement::List elements = otherSchema->elements();
+ for (int i = 0; i < elements.count(); ++i) {
+ if (!m_mergedSchema->element(elements.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addElement(elements.at(i));
+ }
+
+ const XsdAttribute::List attributes = otherSchema->attributes();
+ for (int i = 0; i < attributes.count(); ++i) {
+ if (!m_mergedSchema->attribute(attributes.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addAttribute(attributes.at(i));
+ }
+
+ const SchemaType::List types = otherSchema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (!m_mergedSchema->type(types.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addType(types.at(i));
+ }
+
+ const SchemaType::List anonymousTypes = otherSchema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ // add anonymous type as they are
+ m_mergedSchema->addAnonymousType(anonymousTypes.at(i));
+ }
+
+ const XsdModelGroup::List elementGroups = otherSchema->elementGroups();
+ for (int i = 0; i < elementGroups.count(); ++i) {
+ if (!m_mergedSchema->elementGroup(elementGroups.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addElementGroup(elementGroups.at(i));
+ }
+
+ const XsdAttributeGroup::List attributeGroups = otherSchema->attributeGroups();
+ for (int i = 0; i < attributeGroups.count(); ++i) {
+ if (!m_mergedSchema->attributeGroup(attributeGroups.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addAttributeGroup(attributeGroups.at(i));
+ }
+
+ const XsdNotation::List notations = otherSchema->notations();
+ for (int i = 0; i < notations.count(); ++i) {
+ if (!m_mergedSchema->notation(notations.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addNotation(notations.at(i));
+ }
+
+ const XsdIdentityConstraint::List identityConstraints = otherSchema->identityConstraints();
+ for (int i = 0; i < identityConstraints.count(); ++i) {
+ if (!m_mergedSchema->identityConstraint(identityConstraints.at(i)->name(otherSchema->namePool())))
+ m_mergedSchema->addIdentityConstraint(identityConstraints.at(i));
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemamerger_p.h b/src/xmlpatterns/schema/qxsdschemamerger_p.h
new file mode 100644
index 0000000..599a08b
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemamerger_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSchemaMerger_H
+#define Patternist_XsdSchemaMerger_H
+
+#include "qxsdschema_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class that merges two schemas into one.
+ *
+ * This class is used in XsdValidatingInstanceReader to merge the schema
+ * given in the constructor with a schema defined in the instance document
+ * via xsi:schemaLocation or xsi:noNamespaceSchema location.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaMerger : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdSchemaMerger> Ptr;
+
+ /**
+ * Creates a new schema merger object that merges @p schema with @p otherSchema.
+ */
+ XsdSchemaMerger(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema);
+
+ /**
+ * Returns the merged schema.
+ */
+ XsdSchema::Ptr mergedSchema() const;
+
+ private:
+ void merge(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema);
+
+ XsdSchema::Ptr m_mergedSchema;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp
new file mode 100644
index 0000000..c57d9fd
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp
@@ -0,0 +1,6119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemaparser_p.h"
+
+#include "private/qxmlutils_p.h"
+#include "qacceltreeresourceloader_p.h"
+#include "qautoptr_p.h"
+#include "qboolean_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qqnamevalue_p.h"
+#include "qxmlquery_p.h"
+#include "qxpathhelper_p.h"
+#include "qxsdattributereference_p.h"
+#include "qxsdreference_p.h"
+#include "qxsdschematoken_p.h"
+
+#include <QtCore/QFile>
+#include <QtXmlPatterns/QXmlQuery>
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * @page schema_overview Overview
+ * @section structure_and_components Structure and Components
+ *
+ * The schema validator code consists of 4 major components
+ *
+ * <dl>
+ * <dt>The schema parser (QPatternist::XsdSchemaParser)</dt>
+ * <dd>This component parses a XML document that is supplied via a QIODevice. It creates
+ * a so called (incomplete) 'compiled schema', which is a representation of the XML Schema
+ * structure as C++ objects.
+ * As the parser is a streaming parser, it can't resolve references to types or elements/attributes
+ * in place, therefor it creates resolver tasks which are passed to the schema resolver component
+ * for resolving at a later point in time.
+ * The parser does furthermore the basic XML structure constraint checking, e.g. if all required
+ * attributes are available or the order of the elements is correct.</dd>
+ *
+ * <dt>The schema resolver (QPatternist::XsdSchemaResolver)</dt>
+ * <dd>This component is activated after the schema parser component has been finished the parsing
+ * of all schemas. The resolver has been supplied with resolve tasks by the schema parser that
+ * it will resolve in this step now. Between working on the single resolver tasks, the resolver
+ * calls check methods from the schema checker component to make sure that some assertions are
+ * valid (e.g. no circular inheritance of types), so that the resolver can work without hassle.
+ * During resoving references to attribute or element groups it also checks for circular references
+ * of these groups.
+ * At the end of that phase we have a compiled schema that is fully resolved (not necessarily valid though).</dd>
+ *
+ * <dt>The schema checker (QPatternist::XsdSchemaChecker)</dt>
+ * <dd>This component does all the schema constraint checking as given by the Schema specification.
+ * At the end of that phase we have fully resolved and valid compiled schema that can be used for validation
+ * of instance documents.</dd>
+ *
+ * <dt>The validator (QPatternist::XsdValidatingInstanceReader)</dt>
+ * <dd>This component is responsible for validating a XML instance document, provided via a QIODevice, against
+ * a valid compiled schema.</dd>
+ * </dl>
+ *
+ * @ingroup Patternist_schema
+ */
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+
+/**
+ * @short A helper class for automatically handling namespace scopes of elements.
+ *
+ * This class should be instantiated at the beginning of each parse XYZ method.
+ */
+class ElementNamespaceHandler
+{
+ public:
+ /**
+ * Creates a new element namespace handler object.
+ *
+ * It checks whether the @p parser is on the right @p tag and it creates a new namespace
+ * context that contains the inherited and local namespace declarations.
+ */
+ ElementNamespaceHandler(const XsdSchemaToken::NodeName &tag, XsdSchemaParser *parser)
+ : m_parser(parser)
+ {
+ Q_ASSERT(m_parser->isStartElement() && (XsdSchemaToken::toToken(m_parser->name()) == tag) && (XsdSchemaToken::toToken(m_parser->namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI));
+ Q_UNUSED(tag)
+ m_parser->m_namespaceSupport.pushContext();
+ m_parser->m_namespaceSupport.setPrefixes(m_parser->namespaceDeclarations());
+ }
+
+ /**
+ * Destroys the element namespace handler object.
+ *
+ * It destroys the local namespace context.
+ */
+ ~ElementNamespaceHandler()
+ {
+ m_parser->m_namespaceSupport.popContext();
+ }
+
+ private:
+ XsdSchemaParser *m_parser;
+};
+
+/**
+ * A helper class that checks for the right occurrence of
+ * xml tags with the help of a DFA.
+ */
+class TagValidationHandler
+{
+ public:
+ TagValidationHandler(XsdTagScope::Type tag, XsdSchemaParser *parser, const NamePool::Ptr &namePool)
+ : m_parser(parser), m_machine(namePool)
+ {
+ Q_ASSERT(m_parser->m_stateMachines.contains(tag));
+
+ m_machine = m_parser->m_stateMachines.value(tag);
+ m_machine.reset();
+ }
+
+ void validate(XsdSchemaToken::NodeName token)
+ {
+ if (token == XsdSchemaToken::NoKeyword) {
+ const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
+
+ QStringList elementNames;
+ for (int i = 0; i < tokens.count(); ++i)
+ elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
+
+ m_parser->error(QtXmlPatterns::tr("Can not process unknown element %1, expected elements are: %2.")
+ .arg(formatElement(m_parser->name().toString()))
+ .arg(elementNames.join(QLatin1String(", "))));
+ return;
+ }
+
+ if (!m_machine.proceed(token)) {
+ const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
+
+ QStringList elementNames;
+ for (int i = 0; i < tokens.count(); ++i)
+ elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
+
+ m_parser->error(QtXmlPatterns::tr("Element %1 is not allowed in this scope, possible elements are: %2.")
+ .arg(formatElement(XsdSchemaToken::toString(token)))
+ .arg(elementNames.join(QLatin1String(", "))));
+ return;
+ }
+ }
+
+ void finalize() const
+ {
+ if (!m_machine.inEndState()) {
+ const QList<XsdSchemaToken::NodeName> tokens = m_machine.possibleTransitions();
+
+ QStringList elementNames;
+ for (int i = 0; i < tokens.count(); ++i)
+ elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i))));
+
+ m_parser->error(QtXmlPatterns::tr("Child element is missing in that scope, possible child elements are: %1.")
+ .arg(elementNames.join(QLatin1String(", "))));
+ }
+ }
+
+ private:
+ XsdSchemaParser *m_parser;
+ XsdStateMachine<XsdSchemaToken::NodeName> m_machine;
+};
+
+}
+
+/**
+ * Returns a list of all particles with group references that appear at any level of
+ * the given unresolved @p group.
+ */
+static XsdParticle::List collectGroupRef(const XsdModelGroup::Ptr &group)
+{
+ XsdParticle::List refParticles;
+
+ XsdParticle::List particles = group->particles();
+ for (int i = 0; i < particles.count(); ++i) {
+ if (particles.at(i)->term()->isReference()) {
+ const XsdReference::Ptr reference(particles.at(i)->term());
+ if (reference->type() == XsdReference::ModelGroup)
+ refParticles.append(particles.at(i));
+ }
+ if (particles.at(i)->term()->isModelGroup()) {
+ refParticles << collectGroupRef(XsdModelGroup::Ptr(particles.at(i)->term()));
+ }
+ }
+
+ return refParticles;
+}
+
+/**
+ * Helper function that works around the limited facilities of
+ * QUrl/AnyURI::fromLexical to detect invalid URIs
+ */
+inline static bool isValidUri(const QString &string)
+{
+ // an empty URI points to the current document as defined in RFC 2396 (4.2)
+ if (string.isEmpty())
+ return true;
+
+ // explicit check as that is not checked by the code below
+ if (string.startsWith(QLatin1String("##")))
+ return false;
+
+ const AnyURI::Ptr uri = AnyURI::fromLexical(string);
+ return (!(uri->hasError()));
+}
+
+XsdSchemaParser::XsdSchemaParser(const XsdSchemaContext::Ptr &context, const XsdSchemaParserContext::Ptr &parserContext, QIODevice *device)
+ : MaintainingReader<XsdSchemaToken, XsdTagScope::Type>(parserContext->elementDescriptions(), QSet<XsdSchemaToken::NodeName>(), context, device)
+ , m_context(context)
+ , m_parserContext(parserContext)
+ , m_namePool(m_parserContext->namePool())
+ , m_namespaceSupport(m_namePool)
+{
+ m_schema = m_parserContext->schema();
+ m_schemaResolver = m_parserContext->resolver();
+ m_idCache = XsdIdCache::Ptr(new XsdIdCache());
+
+ setupStateMachines();
+ setupBuiltinTypeNames();
+}
+
+void XsdSchemaParser::addIncludedSchemas(const NamespaceSet &schemas)
+{
+ m_includedSchemas += schemas;
+}
+
+void XsdSchemaParser::setIncludedSchemas(const NamespaceSet &schemas)
+{
+ m_includedSchemas = schemas;
+}
+
+void XsdSchemaParser::addImportedSchemas(const NamespaceSet &schemas)
+{
+ m_importedSchemas += schemas;
+}
+
+void XsdSchemaParser::setImportedSchemas(const NamespaceSet &schemas)
+{
+ m_importedSchemas = schemas;
+}
+
+void XsdSchemaParser::addRedefinedSchemas(const NamespaceSet &schemas)
+{
+ m_redefinedSchemas += schemas;
+}
+
+void XsdSchemaParser::setRedefinedSchemas(const NamespaceSet &schemas)
+{
+ m_redefinedSchemas = schemas;
+}
+
+void XsdSchemaParser::setTargetNamespace(const QString &targetNamespace)
+{
+ m_targetNamespace = targetNamespace;
+}
+
+void XsdSchemaParser::setTargetNamespaceExtended(const QString &targetNamespace)
+{
+ m_targetNamespace = targetNamespace;
+ m_namespaceSupport.setTargetNamespace(m_namePool->allocateNamespace(m_targetNamespace));
+}
+
+void XsdSchemaParser::setDocumentURI(const QUrl &uri)
+{
+ m_documentURI = uri;
+
+ // prevent to get included/imported/redefined twice
+ m_includedSchemas.insert(uri);
+ m_importedSchemas.insert(uri);
+ m_redefinedSchemas.insert(uri);
+}
+
+QUrl XsdSchemaParser::documentURI() const
+{
+ return m_documentURI;
+}
+
+bool XsdSchemaParser::isAnyAttributeAllowed() const
+{
+ return false;
+}
+
+bool XsdSchemaParser::parse(ParserType parserType)
+{
+ m_componentLocationHash.clear();
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ if (isSchemaTag(XsdSchemaToken::Schema, token, namespaceToken)) {
+ parseSchema(parserType);
+ } else {
+ error(QtXmlPatterns::tr("Document is not a XML schema."));
+ }
+ }
+ }
+
+ m_schemaResolver->addComponentLocationHash(m_componentLocationHash);
+ m_schemaResolver->setDefaultOpenContent(m_defaultOpenContent, m_defaultOpenContentAppliesToEmpty);
+
+ if (QXmlStreamReader::error() != QXmlStreamReader::NoError)
+ error(errorString());
+
+ return true;
+}
+
+void XsdSchemaParser::error(const QString &msg)
+{
+ MaintainingReader<XsdSchemaToken, XsdTagScope::Type>::error(msg, XsdSchemaContext::XSDError);
+}
+
+void XsdSchemaParser::attributeContentError(const char *attributeName, const char *elementName, const QString &value, const SchemaType::Ptr &type)
+{
+ if (type) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element contains invalid content: {%3} is not a value of type %4.")
+ .arg(formatAttribute(attributeName))
+ .arg(formatElement(elementName))
+ .arg(formatData(value))
+ .arg(formatType(m_namePool, type)));
+ } else {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element contains invalid content: {%3}.")
+ .arg(formatAttribute(attributeName))
+ .arg(formatElement(elementName))
+ .arg(formatData(value)));
+ }
+}
+
+void XsdSchemaParser::parseSchema(ParserType parserType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Schema, this);
+
+ validateElement(XsdTagScope::Schema);
+
+ // parse attributes
+
+ if (parserType == TopLevelParser) {
+ if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
+ m_targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
+ }
+ } else if (parserType == IncludeParser) {
+ // m_targetNamespace is set to the target namespace of the including schema at this point
+
+ if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
+ const QString targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
+
+ if (m_targetNamespace != targetNamespace) {
+ error(QtXmlPatterns::tr("Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema.")
+ .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace)));
+ return;
+ }
+ }
+ } else if (parserType == ImportParser) {
+ // m_targetNamespace is set to the target namespace from the namespace attribute of the <import> tag at this point
+
+ QString targetNamespace;
+ if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
+ targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
+ }
+
+ if (m_targetNamespace != targetNamespace) {
+ error(QtXmlPatterns::tr("Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema.")
+ .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace)));
+ return;
+ }
+ } else if (parserType == RedefineParser) {
+ // m_targetNamespace is set to the target namespace of the redefining schema at this point
+
+ if (hasAttribute(QString::fromLatin1("targetNamespace"))) {
+ const QString targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema");
+
+ if (m_targetNamespace != targetNamespace) {
+ error(QtXmlPatterns::tr("Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema.")
+ .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace)));
+ return;
+ }
+ }
+ }
+
+ if (hasAttribute(QString::fromLatin1("attributeFormDefault"))) {
+ const QString value = readAttribute(QString::fromLatin1("attributeFormDefault"));
+ if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
+ attributeContentError("attributeFormDefault", "schema", value);
+ return;
+ }
+
+ m_attributeFormDefault = value;
+ } else {
+ m_attributeFormDefault = QString::fromLatin1("unqualified");
+ }
+
+ if (hasAttribute(QString::fromLatin1("elementFormDefault"))) {
+ const QString value = readAttribute(QString::fromLatin1("elementFormDefault"));
+ if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
+ attributeContentError("elementFormDefault", "schema", value);
+ return;
+ }
+
+ m_elementFormDefault = value;
+ } else {
+ m_elementFormDefault = QString::fromLatin1("unqualified");
+ }
+
+ if (hasAttribute(QString::fromLatin1("blockDefault"))) {
+ const QString blockDefault = readAttribute(QString::fromLatin1("blockDefault"));
+ const QStringList blockDefaultList = blockDefault.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < blockDefaultList.count(); ++i) {
+ const QString value = blockDefaultList.at(i);
+ if (value != QString::fromLatin1("#all") &&
+ value != QString::fromLatin1("extension") &&
+ value != QString::fromLatin1("restriction") &&
+ value != QString::fromLatin1("substitution")) {
+ attributeContentError("blockDefault", "schema", value);
+ return;
+ }
+ }
+
+ m_blockDefault = blockDefault;
+ }
+
+ if (hasAttribute(QString::fromLatin1("finalDefault"))) {
+ const QString finalDefault = readAttribute(QString::fromLatin1("finalDefault"));
+ const QStringList finalDefaultList = finalDefault.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < finalDefaultList.count(); ++i) {
+ const QString value = finalDefaultList.at(i);
+ if (value != QString::fromLatin1("#all") &&
+ value != QString::fromLatin1("extension") &&
+ value != QString::fromLatin1("restriction") &&
+ value != QString::fromLatin1("list") &&
+ value != QString::fromLatin1("union")) {
+ attributeContentError("finalDefault", "schema", value);
+ return;
+ }
+ }
+
+ m_finalDefault = finalDefault;
+ }
+
+ if (hasAttribute(QString::fromLatin1("xpathDefaultNamespace"))) {
+ const QString xpathDefaultNamespace = readAttribute(QString::fromLatin1("xpathDefaultNamespace"));
+ if (xpathDefaultNamespace != QString::fromLatin1("##defaultNamespace") &&
+ xpathDefaultNamespace != QString::fromLatin1("##targetNamespace") &&
+ xpathDefaultNamespace != QString::fromLatin1("##local")) {
+ if (!isValidUri(xpathDefaultNamespace)) {
+ attributeContentError("xpathDefaultNamespace", "schema", xpathDefaultNamespace);
+ return;
+ }
+ }
+ m_xpathDefaultNamespace = xpathDefaultNamespace;
+ } else {
+ m_xpathDefaultNamespace = QString::fromLatin1("##local");
+ }
+
+ if (hasAttribute(QString::fromLatin1("defaultAttributes"))) {
+ const QString attrGroupName = readQNameAttribute(QString::fromLatin1("defaultAttributes"), "schema");
+ convertName(attrGroupName, NamespaceSupport::ElementName, m_defaultAttributes); // translate qualified name into QXmlName
+ }
+
+ if (hasAttribute(QString::fromLatin1("version"))) {
+ const QString version = readAttribute(QString::fromLatin1("version"));
+ }
+
+ if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) {
+ const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML);
+
+ const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"));
+ if (!exp.exactMatch(value)) {
+ attributeContentError("xml:lang", "schema", value);
+ return;
+ }
+ }
+
+ validateIdAttribute("schema");
+
+ TagValidationHandler tagValidator(XsdTagScope::Schema, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Include, token, namespaceToken)) {
+ parseInclude();
+ } else if (isSchemaTag(XsdSchemaToken::Import, token, namespaceToken)) {
+ parseImport();
+ } else if (isSchemaTag(XsdSchemaToken::Redefine, token, namespaceToken)) {
+ parseRedefine();
+ } else if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ m_schema->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::DefaultOpenContent, token, namespaceToken)) {
+ parseDefaultOpenContent();
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ const XsdSimpleType::Ptr type = parseGlobalSimpleType();
+ addType(type);
+ } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
+ const XsdComplexType::Ptr type = parseGlobalComplexType();
+ addType(type);
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdModelGroup::Ptr group = parseNamedGroup();
+ addElementGroup(group);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ XsdAttributeGroup::Ptr attributeGroup = parseNamedAttributeGroup();
+ addAttributeGroup(attributeGroup);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdElement::Ptr element = parseGlobalElement();
+ addElement(element);
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttribute::Ptr attribute = parseGlobalAttribute();
+ addAttribute(attribute);
+ } else if (isSchemaTag(XsdSchemaToken::Notation, token, namespaceToken)) {
+ const XsdNotation::Ptr notation = parseNotation();
+ addNotation(notation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ m_schema->setTargetNamespace(m_targetNamespace);
+}
+
+void XsdSchemaParser::parseInclude()
+{
+ Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Include &&
+ XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI);
+
+ validateElement(XsdTagScope::Include);
+
+ // parse attributes
+ const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
+
+ QUrl url(schemaLocation);
+ if (url.isRelative()) {
+ Q_ASSERT(m_documentURI.isValid());
+
+ url = m_documentURI.resolved(url);
+ }
+
+ if (m_includedSchemas.contains(url)) {
+ // we have included that file already, according to the schema spec we are
+ // allowed to silently skip it.
+ } else {
+ m_includedSchemas.insert(url);
+
+ const AutoPtr<QNetworkReply> reply(AccelTreeResourceLoader::load(url, m_context->networkAccessManager(),
+ m_context, AccelTreeResourceLoader::ContinueOnError));
+ if (reply) {
+ // parse the included schema by a different parser but with the same context
+ XsdSchemaParser parser(m_context, m_parserContext, reply.data());
+ parser.setDocumentURI(url);
+ parser.setTargetNamespaceExtended(m_targetNamespace);
+ parser.setIncludedSchemas(m_includedSchemas);
+ parser.setImportedSchemas(m_importedSchemas);
+ parser.setRedefinedSchemas(m_redefinedSchemas);
+ if (!parser.parse(XsdSchemaParser::IncludeParser)) {
+ return;
+ } else {
+ // add indirectly loaded schemas to the list of already loaded ones
+ addIncludedSchemas(parser.m_includedSchemas);
+ addImportedSchemas(parser.m_importedSchemas);
+ addRedefinedSchemas(parser.m_redefinedSchemas);
+ }
+ }
+ }
+
+ validateIdAttribute("include");
+
+ TagValidationHandler tagValidator(XsdTagScope::Include, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ m_schema->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseImport()
+{
+ Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Import &&
+ XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI);
+
+ validateElement(XsdTagScope::Import);
+
+ // parse attributes
+ QString importNamespace;
+ if (hasAttribute(QString::fromLatin1("namespace"))) {
+ importNamespace = readAttribute(QString::fromLatin1("namespace"));
+ if (importNamespace == m_targetNamespace) {
+ error(QtXmlPatterns::tr("%1 element is not allowed to have the same %2 attribute value as the target namespace %3.")
+ .arg(formatElement("import"))
+ .arg(formatAttribute("namespace"))
+ .arg(formatURI(m_targetNamespace)));
+ return;
+ }
+ } else {
+ if (m_targetNamespace.isEmpty()) {
+ error(QtXmlPatterns::tr("%1 element without %2 attribute is not allowed inside schema without target namespace.")
+ .arg(formatElement("import"))
+ .arg(formatAttribute("namespace")));
+ return;
+ }
+ }
+
+ if (hasAttribute(QString::fromLatin1("schemaLocation"))) {
+ const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
+
+ QUrl url(schemaLocation);
+ if (url.isRelative()) {
+ Q_ASSERT(m_documentURI.isValid());
+
+ url = m_documentURI.resolved(url);
+ }
+
+ if (m_importedSchemas.contains(url)) {
+ // we have imported that file already, according to the schema spec we are
+ // allowed to silently skip it.
+ } else {
+ m_importedSchemas.insert(url);
+
+ // as it is possible that well known schemas (e.g. XSD for XML) are only referenced by
+ // namespace we should add it as well
+ m_importedSchemas.insert(importNamespace);
+
+ AutoPtr<QNetworkReply> reply(AccelTreeResourceLoader::load(url, m_context->networkAccessManager(),
+ m_context, AccelTreeResourceLoader::ContinueOnError));
+ if (reply) {
+ // parse the included schema by a different parser but with the same context
+ XsdSchemaParser parser(m_context, m_parserContext, reply.data());
+ parser.setDocumentURI(url);
+ parser.setTargetNamespace(importNamespace);
+ parser.setIncludedSchemas(m_includedSchemas);
+ parser.setImportedSchemas(m_importedSchemas);
+ parser.setRedefinedSchemas(m_redefinedSchemas);
+ if (!parser.parse(XsdSchemaParser::ImportParser)) {
+ return;
+ } else {
+ // add indirectly loaded schemas to the list of already loaded ones
+ addIncludedSchemas(parser.m_includedSchemas);
+ addImportedSchemas(parser.m_importedSchemas);
+ addRedefinedSchemas(parser.m_redefinedSchemas);
+ }
+ }
+ }
+ } else {
+ // check whether it is a known namespace we have a builtin schema for
+ if (!importNamespace.isEmpty()) {
+ if (!m_importedSchemas.contains(importNamespace)) {
+ m_importedSchemas.insert(importNamespace);
+
+ QFile file(QString::fromLatin1(":") + importNamespace);
+ if (file.open(QIODevice::ReadOnly)) {
+ XsdSchemaParser parser(m_context, m_parserContext, &file);
+ parser.setDocumentURI(importNamespace);
+ parser.setTargetNamespace(importNamespace);
+ parser.setIncludedSchemas(m_includedSchemas);
+ parser.setImportedSchemas(m_importedSchemas);
+ parser.setRedefinedSchemas(m_redefinedSchemas);
+ if (!parser.parse(XsdSchemaParser::ImportParser)) {
+ return;
+ } else {
+ // add indirectly loaded schemas to the list of already loaded ones
+ addIncludedSchemas(parser.m_includedSchemas);
+ addImportedSchemas(parser.m_importedSchemas);
+ addRedefinedSchemas(parser.m_redefinedSchemas);
+ }
+ }
+ }
+ } else {
+ // we don't import anything... that is valid according to the schema
+ }
+ }
+
+ validateIdAttribute("import");
+
+ TagValidationHandler tagValidator(XsdTagScope::Import, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ m_schema->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseRedefine()
+{
+ Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Redefine &&
+ XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI);
+
+ validateElement(XsdTagScope::Redefine);
+
+ // parse attributes
+ validateIdAttribute("redefine");
+
+ const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation"));
+
+ TagValidationHandler tagValidator(XsdTagScope::Redefine, this, m_namePool);
+
+ XsdSimpleType::List redefinedSimpleTypes;
+ XsdComplexType::List redefinedComplexTypes;
+ XsdModelGroup::List redefinedGroups;
+ XsdAttributeGroup::List redefinedAttributeGroups;
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ m_schema->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ const XsdSimpleType::Ptr type = parseGlobalSimpleType();
+ redefinedSimpleTypes.append(type);
+
+ const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type);
+ if (baseTypeName != type->name(m_namePool)) {
+ error(QString::fromLatin1("redefined simple type %1 must have itself as base type").arg(formatType(m_namePool, type)));
+ return;
+ }
+ } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
+ const XsdComplexType::Ptr type = parseGlobalComplexType();
+ redefinedComplexTypes.append(type);
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
+
+ // 5
+ const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type);
+ if (baseTypeName != type->name(m_namePool)) {
+ error(QString::fromLatin1("redefined complex type %1 must have itself as base type").arg(formatType(m_namePool, type)));
+ return;
+ }
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdModelGroup::Ptr group = parseNamedGroup();
+ redefinedGroups.append(group);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeGroup::Ptr group = parseNamedAttributeGroup();
+ redefinedAttributeGroups.append(group);
+
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ bool locationMustResolve = false;
+ if (!redefinedSimpleTypes.isEmpty() || !redefinedComplexTypes.isEmpty() ||
+ !redefinedGroups.isEmpty() || !redefinedAttributeGroups.isEmpty()) {
+ locationMustResolve = true;
+ }
+
+ QUrl url(schemaLocation);
+ if (url.isRelative()) {
+ Q_ASSERT(m_documentURI.isValid());
+
+ url = m_documentURI.resolved(url);
+ }
+
+ // we parse the schema given in the redefine tag into its own context
+ const XsdSchemaParserContext::Ptr redefinedContext(new XsdSchemaParserContext(m_namePool, m_context));
+
+ if (m_redefinedSchemas.contains(url)) {
+ // we have redefined that file already, according to the schema spec we are
+ // allowed to silently skip it.
+ } else {
+ m_redefinedSchemas.insert(url);
+ QNetworkReply *reply = AccelTreeResourceLoader::load(url, m_context->networkAccessManager(),
+ m_context,
+ (locationMustResolve ? AccelTreeResourceLoader::FailOnError : AccelTreeResourceLoader::ContinueOnError));
+ if (reply) {
+ // parse the included schema by a different parser but with the same context
+ XsdSchemaParser parser(m_context, redefinedContext, reply);
+ parser.setDocumentURI(url);
+ parser.setTargetNamespaceExtended(m_targetNamespace);
+ parser.setIncludedSchemas(m_includedSchemas);
+ parser.setImportedSchemas(m_importedSchemas);
+ parser.setRedefinedSchemas(m_redefinedSchemas);
+ if (!parser.parse(XsdSchemaParser::RedefineParser)) {
+ return;
+ } else {
+ // add indirectly loaded schemas to the list of already loaded ones
+ addIncludedSchemas(parser.m_includedSchemas);
+ addImportedSchemas(parser.m_importedSchemas);
+ addRedefinedSchemas(parser.m_redefinedSchemas);
+ }
+
+ delete reply;
+ }
+ }
+
+ XsdSimpleType::List contextSimpleTypes = redefinedContext->schema()->simpleTypes();
+ XsdComplexType::List contextComplexTypes = redefinedContext->schema()->complexTypes();
+ XsdModelGroup::List contextGroups = redefinedContext->schema()->elementGroups();
+ XsdAttributeGroup::List contextAttributeGroups = redefinedContext->schema()->attributeGroups();
+
+ // now we do the actual redefinition:
+
+ // iterate over all redefined simple types
+ for (int i = 0; i < redefinedSimpleTypes.count(); ++i) {
+ XsdSimpleType::Ptr redefinedType = redefinedSimpleTypes.at(i);
+
+ //TODONEXT: validation
+
+ // search the definition they override in the context types
+ bool found = false;
+ for (int j = 0; j < contextSimpleTypes.count(); ++j) {
+ XsdSimpleType::Ptr contextType = contextSimpleTypes.at(j);
+
+ if (redefinedType->name(m_namePool) == contextType->name(m_namePool)) { // we found the right type
+ found = true;
+
+ // 1) set name of context type to empty name
+ contextType->setName(m_parserContext->createAnonymousName(QString()));
+
+ // 2) set the context type as base type for the redefined type
+ redefinedType->setWxsSuperType(contextType);
+
+ // 3) remove the base type resolving job from the resolver as
+ // we have set the base type here explicitly
+ m_parserContext->resolver()->removeSimpleRestrictionBase(redefinedType);
+
+ // 4) add the redefined type to the schema
+ addType(redefinedType);
+
+ // 5) add the context type as anonymous type, so the resolver
+ // can resolve it further.
+ addAnonymousType(contextType);
+
+ // 6) remove the context type from the list
+ contextSimpleTypes.removeAt(j);
+
+ break;
+ }
+ }
+
+ if (!found) {
+ error(QString::fromLatin1("no matching type found to redefine simple type %1").arg(formatType(m_namePool, redefinedType)));
+ return;
+ }
+ }
+
+ // add all remaining context simple types to the schema
+ for (int i = 0; i < contextSimpleTypes.count(); ++i) {
+ addType(contextSimpleTypes.at(i));
+ }
+
+ // iterate over all redefined complex types
+ for (int i = 0; i < redefinedComplexTypes.count(); ++i) {
+ XsdComplexType::Ptr redefinedType = redefinedComplexTypes.at(i);
+
+ //TODONEXT: validation
+
+ // search the definition they override in the context types
+ bool found = false;
+ for (int j = 0; j < contextComplexTypes.count(); ++j) {
+ XsdComplexType::Ptr contextType = contextComplexTypes.at(j);
+
+ if (redefinedType->name(m_namePool) == contextType->name(m_namePool)) { // we found the right type
+ found = true;
+
+ // 1) set name of context type to empty name
+ contextType->setName(m_parserContext->createAnonymousName(QString()));
+
+ // 2) set the context type as base type for the redefined type
+ redefinedType->setWxsSuperType(contextType);
+
+ // 3) remove the base type resolving job from the resolver as
+ // we have set the base type here explicitly
+ m_parserContext->resolver()->removeComplexBaseType(redefinedType);
+
+ // 4) add the redefined type to the schema
+ addType(redefinedType);
+
+ // 5) add the context type as anonymous type, so the resolver
+ // can resolve its attribute uses etc.
+ addAnonymousType(contextType);
+
+ // 6) remove the context type from the list
+ contextComplexTypes.removeAt(j);
+
+ break;
+ }
+ }
+
+ if (!found) {
+ error(QString::fromLatin1("no matching type found to redefine complex type %1").arg(formatType(m_namePool, redefinedType)));
+ return;
+ }
+ }
+
+ // iterate over all redefined element groups
+ for (int i = 0; i < redefinedGroups.count(); ++i) {
+ const XsdModelGroup::Ptr group(redefinedGroups.at(i));
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
+
+ // 6
+ const XsdParticle::List particles = collectGroupRef(group);
+ XsdParticle::Ptr referencedParticle;
+ int sameNameCounter = 0;
+ for (int i = 0; i < particles.count(); ++i) {
+ const XsdReference::Ptr ref(particles.at(i)->term());
+ if (ref->referenceName() == group->name(m_namePool)) {
+ referencedParticle = particles.at(i);
+
+ if (referencedParticle->minimumOccurs() != 1 || referencedParticle->maximumOccurs() != 1 || referencedParticle->maximumOccursUnbounded()) { // 6.1.2
+ error(QString::fromLatin1("redefined group %1 can not contain reference to itself with minOccurs or maxOccurs != 1").arg(formatKeyword(group->displayName(m_namePool))));
+ return;
+ }
+ sameNameCounter++;
+ }
+ }
+
+ // 6.1.1
+ if (sameNameCounter > 1) {
+ error(QString::fromLatin1("redefined group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(m_namePool))));
+ return;
+ }
+
+ // search the group definition in the included schema (S2)
+ XsdModelGroup::Ptr contextGroup;
+ for (int j = 0; j < contextGroups.count(); ++j) {
+ if (group->name(m_namePool) == contextGroups.at(j)->name(m_namePool)) {
+ contextGroup = contextGroups.at(j);
+ break;
+ }
+ }
+
+ if (!contextGroup) { // 6.2.1
+ error(QString::fromLatin1("redefined group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(m_namePool))));
+ return;
+ }
+
+ if (sameNameCounter == 1) {
+ // there was a self reference in the redefined group, so use the
+ // group from the included schema
+
+ // set a anonymous name to the group of the included schema
+ contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(m_namePool).namespaceURI())));
+
+ // replace the self-reference with the group from the included schema
+ referencedParticle->setTerm(contextGroup);
+
+ addElementGroup(group);
+
+ addElementGroup(contextGroup);
+ contextGroups.removeAll(contextGroup);
+ } else {
+ // there was no self reference in the redefined group
+
+ // just add the redefined group...
+ addElementGroup(group);
+
+ // we have to add them, otherwise it is not resolved and we can't validate it later
+ contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(m_namePool).namespaceURI())));
+ addElementGroup(contextGroup);
+
+ m_schemaResolver->addRedefinedGroups(group, contextGroup);
+
+ // ...and forget about the group from the included schema
+ contextGroups.removeAll(contextGroup);
+ }
+ }
+
+ // iterate over all redefined attribute groups
+ for (int i = 0; i < redefinedAttributeGroups.count(); ++i) {
+ const XsdAttributeGroup::Ptr group(redefinedAttributeGroups.at(i));
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine
+
+ // 7
+
+ // 7.1
+ int sameNameCounter = 0;
+ for (int j = 0; j < group->attributeUses().count(); ++j) {
+ const XsdAttributeUse::Ptr attributeUse(group->attributeUses().at(j));
+ if (attributeUse->isReference()) {
+ const XsdAttributeReference::Ptr reference(attributeUse);
+ if (reference->type() == XsdAttributeReference::AttributeGroup) {
+ if (group->name(m_namePool) == reference->referenceName())
+ sameNameCounter++;
+ }
+ }
+ }
+ if (sameNameCounter > 1) {
+ error(QString::fromLatin1("redefined attribute group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(m_namePool))));
+ return;
+ }
+
+ // search the attribute group definition in the included schema (S2)
+ XsdAttributeGroup::Ptr baseGroup;
+ for (int j = 0; j < contextAttributeGroups.count(); ++j) {
+ const XsdAttributeGroup::Ptr contextGroup(contextAttributeGroups.at(j));
+ if (group->name(m_namePool) == contextGroup->name(m_namePool)) {
+ baseGroup = contextGroup;
+ break;
+ }
+ }
+
+ if (!baseGroup) { // 7.2.1
+ error(QString::fromLatin1("redefined attribute group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(m_namePool))));
+ return;
+ }
+
+ if (sameNameCounter == 1) {
+
+ // first set an anonymous name to the attribute group from the included
+ // schema
+ baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(m_namePool).namespaceURI())));
+
+ // iterate over the attribute uses of the redefined attribute group
+ // and replace the self-reference with the attribute group from the
+ // included schema
+ for (int j = 0; j < group->attributeUses().count(); ++j) {
+ const XsdAttributeUse::Ptr attributeUse(group->attributeUses().at(j));
+ if (attributeUse->isReference()) {
+ const XsdAttributeReference::Ptr reference(attributeUse);
+ if (reference->type() == XsdAttributeReference::AttributeGroup) {
+ if (group->name(m_namePool) == reference->referenceName()) {
+ reference->setReferenceName(baseGroup->name(m_namePool));
+ break;
+ }
+ }
+ }
+ }
+
+ // add both groups to the target schema
+ addAttributeGroup(baseGroup);
+ addAttributeGroup(group);
+
+ contextAttributeGroups.removeAll(baseGroup);
+ }
+
+ if (sameNameCounter == 0) { // 7.2
+
+ // we have to add them, otherwise it is not resolved and we can't validate it later
+ baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(m_namePool).namespaceURI())));
+ addAttributeGroup(baseGroup);
+
+ m_schemaResolver->addRedefinedAttributeGroups(group, baseGroup);
+
+ // just add the redefined attribute group to the target schema...
+ addAttributeGroup(group);
+
+ // ... and forget about the one from the included schema
+ contextAttributeGroups.removeAll(baseGroup);
+ }
+ }
+
+ // add all remaining context complex types to the schema
+ for (int i = 0; i < contextComplexTypes.count(); ++i) {
+ addType(contextComplexTypes.at(i));
+ }
+
+ // add all remaining context element groups to the schema
+ for (int i = 0; i < contextGroups.count(); ++i) {
+ addElementGroup(contextGroups.at(i));
+ }
+
+ // add all remaining context attribute groups to the schema
+ for (int i = 0; i < contextAttributeGroups.count(); ++i) {
+ addAttributeGroup(contextAttributeGroups.at(i));
+ }
+
+ // copy all elements, attributes and notations
+ const XsdElement::List contextElements = redefinedContext->schema()->elements();
+ for (int i = 0; i < contextElements.count(); ++i) {
+ addElement(contextElements.at(i));
+ }
+
+ const XsdAttribute::List contextAttributes = redefinedContext->schema()->attributes();
+ for (int i = 0; i < contextAttributes.count(); ++i) {
+ addAttribute(contextAttributes.at(i));
+ }
+
+ const XsdNotation::List contextNotations = redefinedContext->schema()->notations();
+ for (int i = 0; i < contextNotations.count(); ++i) {
+ addNotation(contextNotations.at(i));
+ }
+
+ // push all data to resolve from the context resolver to our resolver
+ redefinedContext->resolver()->copyDataTo(m_parserContext->resolver());
+
+ tagValidator.finalize();
+}
+
+XsdAnnotation::Ptr XsdSchemaParser::parseAnnotation()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Annotation, this);
+
+ validateElement(XsdTagScope::Annotation);
+
+ // parse attributes
+ validateIdAttribute("annotation");
+
+ TagValidationHandler tagValidator(XsdTagScope::Annotation, this, m_namePool);
+
+ const XsdAnnotation::Ptr annotation(new XsdAnnotation());
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Appinfo, token, namespaceToken)) {
+ const XsdApplicationInformation::Ptr info = parseAppInfo();
+ annotation->addApplicationInformation(info);
+ } else if (isSchemaTag(XsdSchemaToken::Documentation, token, namespaceToken)) {
+ const XsdDocumentation::Ptr documentation = parseDocumentation();
+ annotation->addDocumentation(documentation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return annotation;
+}
+
+XsdApplicationInformation::Ptr XsdSchemaParser::parseAppInfo()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Appinfo, this);
+
+ validateElement(XsdTagScope::AppInfo);
+
+ const XsdApplicationInformation::Ptr info(new XsdApplicationInformation());
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("source"))) {
+ const QString value = readAttribute(QString::fromLatin1("source"));
+
+ if (!isValidUri(value)) {
+ attributeContentError("source", "appinfo", value, BuiltinTypes::xsAnyURI);
+ return info;
+ }
+
+ if (!value.isEmpty()) {
+ const AnyURI::Ptr source = AnyURI::fromLexical(value);
+ info->setSource(source);
+ }
+ }
+
+ while (!atEnd()) { //EVAL: can be anything... what to do?
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement())
+ parseUnknownDocumentation();
+ }
+
+ return info;
+}
+
+XsdDocumentation::Ptr XsdSchemaParser::parseDocumentation()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Documentation, this);
+
+ validateElement(XsdTagScope::Documentation);
+
+ const XsdDocumentation::Ptr documentation(new XsdDocumentation());
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("source"))) {
+ const QString value = readAttribute(QString::fromLatin1("source"));
+
+ if (!isValidUri(value)) {
+ attributeContentError("source", "documentation", value, BuiltinTypes::xsAnyURI);
+ return documentation;
+ }
+
+ if (!value.isEmpty()) {
+ const AnyURI::Ptr source = AnyURI::fromLexical(value);
+ documentation->setSource(source);
+ }
+ }
+
+ if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) {
+ const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML);
+
+ const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"));
+ if (!exp.exactMatch(value)) {
+ attributeContentError("xml:lang", "documentation", value);
+ return documentation;
+ }
+ }
+
+ while (!atEnd()) { //EVAL: can by any... what to do?
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement())
+ parseUnknownDocumentation();
+ }
+
+ return documentation;
+}
+
+void XsdSchemaParser::parseDefaultOpenContent()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::DefaultOpenContent, this);
+
+ validateElement(XsdTagScope::DefaultOpenContent);
+
+ m_defaultOpenContent = XsdComplexType::OpenContent::Ptr(new XsdComplexType::OpenContent());
+
+ if (hasAttribute(QString::fromLatin1("appliesToEmpty"))) {
+ const QString value = readAttribute(QString::fromLatin1("appliesToEmpty"));
+ const Boolean::Ptr appliesToEmpty = Boolean::fromLexical(value);
+ if (appliesToEmpty->hasError()) {
+ attributeContentError("appliesToEmpty", "defaultOpenContent", value, BuiltinTypes::xsBoolean);
+ return;
+ }
+
+ m_defaultOpenContentAppliesToEmpty = appliesToEmpty->as<Boolean>()->value();
+ } else {
+ m_defaultOpenContentAppliesToEmpty = false;
+ }
+
+ if (hasAttribute(QString::fromLatin1("mode"))) {
+ const QString mode = readAttribute(QString::fromLatin1("mode"));
+
+ if (mode == QString::fromLatin1("interleave")) {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave);
+ } else if (mode == QString::fromLatin1("suffix")) {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Suffix);
+ } else {
+ attributeContentError("mode", "defaultOpenContent", mode);
+ return;
+ }
+ } else {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave);
+ }
+
+ validateIdAttribute("defaultOpenContent");
+
+ TagValidationHandler tagValidator(XsdTagScope::DefaultOpenContent, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ m_defaultOpenContent->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle;
+ const XsdWildcard::Ptr wildcard = parseAny(particle);
+ m_defaultOpenContent->setWildcard(wildcard);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+XsdSimpleType::Ptr XsdSchemaParser::parseGlobalSimpleType()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleType, this);
+
+ validateElement(XsdTagScope::GlobalSimpleType);
+
+ const XsdSimpleType::Ptr simpleType(new XsdSimpleType());
+ simpleType->setCategory(XsdSimpleType::SimpleTypeAtomic); // just to make sure it's not invalid
+
+ // parse attributes
+ const SchemaType::DerivationConstraints allowedConstraints(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint | SchemaType::ListConstraint | SchemaType::UnionConstraint);
+ simpleType->setDerivationConstraints(readDerivationConstraintAttribute(allowedConstraints, "simpleType"));
+
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("simpleType"));
+ simpleType->setName(objectName);
+
+ validateIdAttribute("simpleType");
+
+ TagValidationHandler tagValidator(XsdTagScope::GlobalSimpleType, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ simpleType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
+ parseSimpleRestriction(simpleType);
+ } else if (isSchemaTag(XsdSchemaToken::List, token, namespaceToken)) {
+ parseList(simpleType);
+ } else if (isSchemaTag(XsdSchemaToken::Union, token, namespaceToken)) {
+ parseUnion(simpleType);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return simpleType;
+}
+
+XsdSimpleType::Ptr XsdSchemaParser::parseLocalSimpleType()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleType, this);
+
+ validateElement(XsdTagScope::LocalSimpleType);
+
+ const XsdSimpleType::Ptr simpleType(new XsdSimpleType());
+ simpleType->setCategory(XsdSimpleType::SimpleTypeAtomic); // just to make sure it's not invalid
+ simpleType->setName(m_parserContext->createAnonymousName(m_targetNamespace));
+
+ validateIdAttribute("simpleType");
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalSimpleType, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ simpleType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
+ parseSimpleRestriction(simpleType);
+ } else if (isSchemaTag(XsdSchemaToken::List, token, namespaceToken)) {
+ parseList(simpleType);
+ } else if (isSchemaTag(XsdSchemaToken::Union, token, namespaceToken)) {
+ parseUnion(simpleType);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return simpleType;
+}
+
+void XsdSchemaParser::parseSimpleRestriction(const XsdSimpleType::Ptr &ptr)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
+
+ validateElement(XsdTagScope::SimpleRestriction);
+
+ ptr->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+
+ // The base attribute and simpleType member are mutually exclusive,
+ // so we keep track of that
+ bool hasBaseAttribute = false;
+ bool hasBaseTypeSpecified = false;
+
+ QXmlName baseName;
+ if (hasAttribute(QString::fromLatin1("base"))) {
+ const QString base = readQNameAttribute(QString::fromLatin1("base"), "restriction");
+ convertName(base, NamespaceSupport::ElementName, baseName); // translate qualified name into QXmlName
+ m_schemaResolver->addSimpleRestrictionBase(ptr, baseName, currentSourceLocation()); // add to resolver
+
+ hasBaseAttribute = true;
+ hasBaseTypeSpecified = true;
+ }
+ validateIdAttribute("restriction");
+
+ XsdFacet::Hash facets;
+ QList<XsdFacet::Ptr> patternFacets;
+ QList<XsdFacet::Ptr> enumerationFacets;
+ QList<XsdFacet::Ptr> assertionFacets;
+
+ TagValidationHandler tagValidator(XsdTagScope::SimpleRestriction, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ ptr->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasBaseAttribute) {
+ error(QtXmlPatterns::tr("%1 element is not allowed inside %2 element if %3 attribute is present.")
+ .arg(formatElement("simpleType"))
+ .arg(formatElement("restriction"))
+ .arg(formatAttribute("base")));
+ return;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(ptr);
+ ptr->setWxsSuperType(type);
+ ptr->setCategory(type->category());
+ hasBaseTypeSpecified = true;
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else if (isSchemaTag(XsdSchemaToken::MinExclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinExclusiveFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::MinInclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinInclusiveFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::MaxExclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxExclusiveFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::MaxInclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxInclusiveFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::TotalDigits, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseTotalDigitsFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::FractionDigits, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseFractionDigitsFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::Length, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseLengthFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::MinLength, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinLengthFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::MaxLength, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxLengthFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::Enumeration, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseEnumerationFacet();
+ enumerationFacets.append(facet);
+ } else if (isSchemaTag(XsdSchemaToken::WhiteSpace, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseWhiteSpaceFacet();
+ addFacet(facet, facets, ptr);
+ } else if (isSchemaTag(XsdSchemaToken::Pattern, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parsePatternFacet();
+ patternFacets.append(facet);
+ } else if (isSchemaTag(XsdSchemaToken::Assertion, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseAssertionFacet();
+ assertionFacets.append(facet);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasBaseTypeSpecified) {
+ error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element.")
+ .arg(formatElement("restriction"))
+ .arg(formatAttribute("base"))
+ .arg(formatElement("simpleType")));
+ return;
+ }
+
+ // merge all pattern facets into one multi value facet
+ if (!patternFacets.isEmpty()) {
+ const XsdFacet::Ptr patternFacet(new XsdFacet());
+ patternFacet->setType(XsdFacet::Pattern);
+
+ AtomicValue::List multiValue;
+ for (int i = 0; i < patternFacets.count(); ++i)
+ multiValue << patternFacets.at(i)->multiValue();
+
+ patternFacet->setMultiValue(multiValue);
+ addFacet(patternFacet, facets, ptr);
+ }
+
+ // merge all enumeration facets into one multi value facet
+ if (!enumerationFacets.isEmpty()) {
+ const XsdFacet::Ptr enumerationFacet(new XsdFacet());
+ enumerationFacet->setType(XsdFacet::Enumeration);
+
+ AtomicValue::List multiValue;
+ for (int i = 0; i < enumerationFacets.count(); ++i)
+ multiValue << enumerationFacets.at(i)->multiValue();
+
+ enumerationFacet->setMultiValue(multiValue);
+ addFacet(enumerationFacet, facets, ptr);
+ }
+
+ // merge all assertion facets into one facet
+ if (!assertionFacets.isEmpty()) {
+ const XsdFacet::Ptr assertionFacet(new XsdFacet());
+ assertionFacet->setType(XsdFacet::Assertion);
+
+ XsdAssertion::List assertions;
+ for (int i = 0; i < assertionFacets.count(); ++i)
+ assertions << assertionFacets.at(i)->assertions();
+
+ assertionFacet->setAssertions(assertions);
+ addFacet(assertionFacet, facets, ptr);
+ }
+
+ ptr->setFacets(facets);
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseList(const XsdSimpleType::Ptr &ptr)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::List, this);
+
+ validateElement(XsdTagScope::List);
+
+ ptr->setCategory(XsdSimpleType::SimpleTypeList);
+ ptr->setDerivationMethod(XsdSimpleType::DerivationList);
+ ptr->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
+
+ // The itemType attribute and simpleType member are mutually exclusive,
+ // so we keep track of that
+ bool hasItemTypeAttribute = false;
+ bool hasItemTypeSpecified = false;
+
+ if (hasAttribute(QString::fromLatin1("itemType"))) {
+ const QString itemType = readQNameAttribute(QString::fromLatin1("itemType"), "list");
+ QXmlName typeName;
+ convertName(itemType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addSimpleListType(ptr, typeName, currentSourceLocation()); // add to resolver
+
+ hasItemTypeAttribute = true;
+ hasItemTypeSpecified = true;
+ }
+
+ validateIdAttribute("list");
+
+ TagValidationHandler tagValidator(XsdTagScope::List, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ ptr->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasItemTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element is not allowed inside %2 element if %3 attribute is present.")
+ .arg(formatElement("simpleType"))
+ .arg(formatElement("list"))
+ .arg(formatAttribute("itemType")));
+ return;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(ptr);
+ ptr->setItemType(type);
+
+ hasItemTypeSpecified = true;
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasItemTypeSpecified) {
+ error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element.")
+ .arg(formatElement("list"))
+ .arg(formatAttribute("itemType"))
+ .arg(formatElement("simpleType")));
+ return;
+ }
+
+ tagValidator.finalize();
+
+ // add the default white space facet that every simple type with list derivation has
+ const XsdFacet::Ptr defaultFacet(new XsdFacet());
+ defaultFacet->setType(XsdFacet::WhiteSpace);
+ defaultFacet->setFixed(true);
+ defaultFacet->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse)));
+ XsdFacet::Hash facets;
+ facets.insert(defaultFacet->type(), defaultFacet);
+ ptr->setFacets(facets);
+}
+
+void XsdSchemaParser::parseUnion(const XsdSimpleType::Ptr &ptr)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Union, this);
+
+ validateElement(XsdTagScope::Union);
+
+ ptr->setCategory(XsdSimpleType::SimpleTypeUnion);
+ ptr->setDerivationMethod(XsdSimpleType::DerivationUnion);
+ ptr->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
+
+ // The memberTypes attribute is not allowed to be empty,
+ // so we keep track of that
+ bool hasMemberTypesAttribute = false;
+ bool hasMemberTypesSpecified = false;
+
+ if (hasAttribute(QString::fromLatin1("memberTypes"))) {
+ hasMemberTypesAttribute = true;
+
+ const QStringList memberTypes = readAttribute(QString::fromLatin1("memberTypes")).split(QLatin1Char(' '), QString::SkipEmptyParts);
+ QList<QXmlName> typeNames;
+
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ QXmlName typeName;
+ convertName(memberTypes.at(i), NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ typeNames.append(typeName);
+ }
+
+ if (!typeNames.isEmpty()) {
+ m_schemaResolver->addSimpleUnionTypes(ptr, typeNames, currentSourceLocation()); // add to resolver
+ hasMemberTypesSpecified = true;
+ }
+ }
+
+ validateIdAttribute("union");
+
+ AnySimpleType::List memberTypes;
+
+ TagValidationHandler tagValidator(XsdTagScope::Union, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ ptr->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(ptr);
+ memberTypes.append(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!memberTypes.isEmpty()) {
+ ptr->setMemberTypes(memberTypes);
+ hasMemberTypesSpecified = true;
+ }
+
+ if (!hasMemberTypesSpecified) {
+ error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element.")
+ .arg(formatElement("union"))
+ .arg(formatAttribute("memberTypes"))
+ .arg(formatElement("simpleType")));
+ return;
+ }
+
+ tagValidator.finalize();
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMinExclusiveFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinExclusive, this);
+
+ validateElement(XsdTagScope::MinExclusiveFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MinimumExclusive);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "minExclusive", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ // as minExclusive can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "minExclusive", value, BuiltinTypes::xsAnySimpleType);
+ return facet;
+ } else {
+ facet->setValue(string);
+ }
+
+ validateIdAttribute("minExclusive");
+
+ TagValidationHandler tagValidator(XsdTagScope::MinExclusiveFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMinInclusiveFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinInclusive, this);
+
+ validateElement(XsdTagScope::MinInclusiveFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MinimumInclusive);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "minInclusive", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ // as minInclusive can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "minInclusive", value, BuiltinTypes::xsAnySimpleType);
+ return facet;
+ } else {
+ facet->setValue(string);
+ }
+
+ validateIdAttribute("minInclusive");
+
+ TagValidationHandler tagValidator(XsdTagScope::MinInclusiveFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMaxExclusiveFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxExclusive, this);
+
+ validateElement(XsdTagScope::MaxExclusiveFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MaximumExclusive);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "maxExclusive", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ // as maxExclusive can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "maxExclusive", value, BuiltinTypes::xsAnySimpleType);
+ return facet;
+ } else {
+ facet->setValue(string);
+ }
+
+ validateIdAttribute("maxExclusive");
+
+ TagValidationHandler tagValidator(XsdTagScope::MaxExclusiveFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMaxInclusiveFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxInclusive, this);
+
+ validateElement(XsdTagScope::MaxInclusiveFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MaximumInclusive);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "maxInclusive", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ // as maxInclusive can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "maxInclusive", value, BuiltinTypes::xsAnySimpleType);
+ return facet;
+ } else {
+ facet->setValue(string);
+ }
+
+ validateIdAttribute("maxInclusive");
+
+ TagValidationHandler tagValidator(XsdTagScope::MaxInclusiveFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseTotalDigitsFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::TotalDigits, this);
+
+ validateElement(XsdTagScope::TotalDigitsFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::TotalDigits);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "totalDigits", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedInteger<TypePositiveInteger>::Ptr integer = DerivedInteger<TypePositiveInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("value", "totalDigits", value, BuiltinTypes::xsPositiveInteger);
+ return facet;
+ } else {
+ facet->setValue(integer);
+ }
+
+ validateIdAttribute("totalDigits");
+
+ TagValidationHandler tagValidator(XsdTagScope::TotalDigitsFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseFractionDigitsFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::FractionDigits, this);
+
+ validateElement(XsdTagScope::FractionDigitsFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::FractionDigits);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "fractionDigits", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("value", "fractionDigits", value, BuiltinTypes::xsNonNegativeInteger);
+ return facet;
+ } else {
+ facet->setValue(integer);
+ }
+
+ validateIdAttribute("fractionDigits");
+
+ TagValidationHandler tagValidator(XsdTagScope::FractionDigitsFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseLengthFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Length, this);
+
+ validateElement(XsdTagScope::LengthFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::Length);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "length", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("value", "length", value, BuiltinTypes::xsNonNegativeInteger);
+ return facet;
+ } else {
+ facet->setValue(integer);
+ }
+
+ validateIdAttribute("length");
+
+ TagValidationHandler tagValidator(XsdTagScope::LengthFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMinLengthFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinLength, this);
+
+ validateElement(XsdTagScope::MinLengthFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MinimumLength);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "minLength", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("value", "minLength", value, BuiltinTypes::xsNonNegativeInteger);
+ return facet;
+ } else {
+ facet->setValue(integer);
+ }
+
+ validateIdAttribute("minLength");
+
+ TagValidationHandler tagValidator(XsdTagScope::MinLengthFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseMaxLengthFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxLength, this);
+
+ validateElement(XsdTagScope::MaxLengthFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::MaximumLength);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "maxLength", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("value", "maxLength", value, BuiltinTypes::xsNonNegativeInteger);
+ return facet;
+ } else {
+ facet->setValue(integer);
+ }
+
+ validateIdAttribute("maxLength");
+
+ TagValidationHandler tagValidator(XsdTagScope::MaxLengthFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseEnumerationFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Enumeration, this);
+
+ validateElement(XsdTagScope::EnumerationFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::Enumeration);
+
+ // parse attributes
+ facet->setFixed(false); // not defined in schema, but can't hurt
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+
+ // as enumeration can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "enumeration", value);
+ return facet;
+ } else {
+ AtomicValue::List multiValue;
+ multiValue << string;
+ facet->setMultiValue(multiValue);
+ }
+ m_schemaResolver->addEnumerationFacetValue(string, m_namespaceSupport);
+
+ validateIdAttribute("enumeration");
+
+ TagValidationHandler tagValidator(XsdTagScope::EnumerationFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseWhiteSpaceFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::WhiteSpace, this);
+
+ validateElement(XsdTagScope::WhiteSpaceFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::WhiteSpace);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ const Boolean::Ptr fixed = Boolean::fromLexical(value);
+ if (fixed->hasError()) {
+ attributeContentError("fixed", "whiteSpace", value, BuiltinTypes::xsBoolean);
+ return facet;
+ }
+
+ facet->setFixed(fixed->as<Boolean>()->value());
+ } else {
+ facet->setFixed(false); // the default value
+ }
+
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ if (value != XsdSchemaToken::toString(XsdSchemaToken::Collapse) &&
+ value != XsdSchemaToken::toString(XsdSchemaToken::Preserve) &&
+ value != XsdSchemaToken::toString(XsdSchemaToken::Replace)) {
+ attributeContentError("value", "whiteSpace", value);
+ return facet;
+ } else {
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "whiteSpace", value);
+ return facet;
+ } else {
+ facet->setValue(string);
+ }
+ }
+
+ validateIdAttribute("whiteSpace");
+
+ TagValidationHandler tagValidator(XsdTagScope::WhiteSpaceFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parsePatternFacet()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Pattern, this);
+
+ validateElement(XsdTagScope::PatternFacet);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::Pattern);
+
+ // parse attributes
+
+ // as pattern can have a value of type anySimpleType, we just read
+ // the string here and store it for later intepretation
+ const QString value = readAttribute(QString::fromLatin1("value"));
+ DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ if (string->hasError()) {
+ attributeContentError("value", "pattern", value);
+ return facet;
+ } else {
+ AtomicValue::List multiValue;
+ multiValue << string;
+ facet->setMultiValue(multiValue);
+ }
+
+ validateIdAttribute("pattern");
+
+ TagValidationHandler tagValidator(XsdTagScope::PatternFacet, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ facet->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return facet;
+}
+
+XsdFacet::Ptr XsdSchemaParser::parseAssertionFacet()
+{
+ // this is just a wrapper function around the parseAssertion() method
+
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assertion, XsdTagScope::Assertion);
+
+ const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet());
+ facet->setType(XsdFacet::Assertion);
+ facet->setAssertions(XsdAssertion::List() << assertion);
+
+ return facet;
+}
+
+XsdComplexType::Ptr XsdSchemaParser::parseGlobalComplexType()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexType, this);
+
+ validateElement(XsdTagScope::GlobalComplexType);
+
+ bool hasTypeSpecified = false;
+ bool hasComplexContent = false;
+
+ const XsdComplexType::Ptr complexType(new XsdComplexType());
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("abstract"))) {
+ const QString abstract = readAttribute(QString::fromLatin1("abstract"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(abstract);
+ if (value->hasError()) {
+ attributeContentError("abstract", "complexType", abstract, BuiltinTypes::xsBoolean);
+ return complexType;
+ }
+
+ complexType->setIsAbstract(value->as<Boolean>()->value());
+ } else {
+ complexType->setIsAbstract(false); // default value
+ }
+
+ complexType->setProhibitedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint, "complexType"));
+ complexType->setDerivationConstraints(readDerivationConstraintAttribute(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint, "complexType"));
+
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("complexType"));
+ complexType->setName(objectName);
+
+ bool effectiveMixed = false;
+ if (hasAttribute(QString::fromLatin1("mixed"))) {
+ const QString mixed = readAttribute(QString::fromLatin1("mixed"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(mixed);
+ if (value->hasError()) {
+ attributeContentError("mixed", "complexType", mixed, BuiltinTypes::xsBoolean);
+ return complexType;
+ }
+
+ effectiveMixed = value->as<Boolean>()->value();
+ }
+
+ validateIdAttribute("complexType");
+
+ TagValidationHandler tagValidator(XsdTagScope::GlobalComplexType, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleContent, token, namespaceToken)) {
+ if (effectiveMixed) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("complexType"))
+ .arg(formatElement("simpleContent"))
+ .arg(formatAttribute("mixed")));
+ return complexType;
+ }
+
+ parseSimpleContent(complexType);
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::ComplexContent, token, namespaceToken)) {
+ bool mixed;
+ parseComplexContent(complexType, &mixed);
+ hasTypeSpecified = true;
+
+ effectiveMixed = (effectiveMixed || mixed);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
+ const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
+ complexType->contentType()->setOpenContent(openContent);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ if (!hasTypeSpecified) {
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ }
+
+ if (hasComplexContent == true) {
+ resolveComplexContentType(complexType, effectiveMixed);
+ }
+
+ return complexType;
+}
+
+XsdComplexType::Ptr XsdSchemaParser::parseLocalComplexType()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexType, this);
+
+ validateElement(XsdTagScope::LocalComplexType);
+
+ bool hasTypeSpecified = false;
+ bool hasComplexContent = true;
+
+ const XsdComplexType::Ptr complexType(new XsdComplexType());
+ complexType->setName(m_parserContext->createAnonymousName(m_targetNamespace));
+
+ // parse attributes
+ bool effectiveMixed = false;
+ if (hasAttribute(QString::fromLatin1("mixed"))) {
+ const QString mixed = readAttribute(QString::fromLatin1("mixed"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(mixed);
+ if (value->hasError()) {
+ attributeContentError("mixed", "complexType", mixed, BuiltinTypes::xsBoolean);
+ return complexType;
+ }
+
+ effectiveMixed = value->as<Boolean>()->value();
+ }
+
+ validateIdAttribute("complexType");
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalComplexType, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleContent, token, namespaceToken)) {
+ parseSimpleContent(complexType);
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::ComplexContent, token, namespaceToken)) {
+ bool mixed;
+ parseComplexContent(complexType, &mixed);
+ hasTypeSpecified = true;
+
+ effectiveMixed = (effectiveMixed || mixed);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
+ const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
+ complexType->contentType()->setOpenContent(openContent);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ if (!hasTypeSpecified) {
+ complexType->setWxsSuperType(BuiltinTypes::xsAnyType);
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ hasComplexContent = true;
+ }
+
+ if (hasComplexContent == true) {
+ resolveComplexContentType(complexType, effectiveMixed);
+ }
+
+ return complexType;
+}
+
+void XsdSchemaParser::resolveComplexContentType(const XsdComplexType::Ptr &complexType, bool effectiveMixed)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctcc.common
+
+ // 1
+ // the effectiveMixed contains the effective mixed value
+
+ // 2
+ bool hasEmptyContent = false;
+ if (!complexType->contentType()->particle()) {
+ hasEmptyContent = true; // 2.1.1
+ } else {
+ if (complexType->contentType()->particle()->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr group = complexType->contentType()->particle()->term();
+ if (group->compositor() == XsdModelGroup::SequenceCompositor || group->compositor() == XsdModelGroup::AllCompositor) {
+ if (group->particles().isEmpty())
+ hasEmptyContent = true; // 2.1.2
+ } else if (group->compositor() == XsdModelGroup::ChoiceCompositor) {
+ if ((complexType->contentType()->particle()->minimumOccurs() == 0) && group->particles().isEmpty())
+ hasEmptyContent = true; // 2.1.3
+ }
+
+ if ((complexType->contentType()->particle()->maximumOccursUnbounded() == false) && (complexType->contentType()->particle()->maximumOccurs() == 0))
+ hasEmptyContent = true; // 2.1.4
+ }
+ }
+
+ const XsdParticle::Ptr explicitContent = (hasEmptyContent ? XsdParticle::Ptr() : complexType->contentType()->particle());
+
+ // do all the other work (3, 4, 5 and 6) in the resolver, as they need access to the base type object
+ m_schemaResolver->addComplexContentType(complexType, explicitContent, effectiveMixed);
+}
+
+void XsdSchemaParser::parseSimpleContent(const XsdComplexType::Ptr &complexType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleContent, this);
+
+ validateElement(XsdTagScope::SimpleContent);
+
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::Simple);
+
+ // parse attributes
+ validateIdAttribute("simpleContent");
+
+ TagValidationHandler tagValidator(XsdTagScope::SimpleContent, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
+ parseSimpleContentRestriction(complexType);
+ } else if (isSchemaTag(XsdSchemaToken::Extension, token, namespaceToken)) {
+ parseSimpleContentExtension(complexType);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseSimpleContentRestriction(const XsdComplexType::Ptr &complexType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
+
+ validateElement(XsdTagScope::SimpleContentRestriction);
+
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+
+ // parse attributes
+ const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "restriction");
+ QXmlName typeName;
+ convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+
+ validateIdAttribute("restriction");
+
+ XsdFacet::Hash facets;
+ QList<XsdFacet::Ptr> patternFacets;
+ QList<XsdFacet::Ptr> enumerationFacets;
+ QList<XsdFacet::Ptr> assertionFacets;
+
+ TagValidationHandler tagValidator(XsdTagScope::SimpleContentRestriction, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(complexType); //TODO: investigate what the schema spec really wants here?!?
+ complexType->contentType()->setSimpleType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else if (isSchemaTag(XsdSchemaToken::MinExclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinExclusiveFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::MinInclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinInclusiveFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::MaxExclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxExclusiveFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::MaxInclusive, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxInclusiveFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::TotalDigits, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseTotalDigitsFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::FractionDigits, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseFractionDigitsFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::Length, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseLengthFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::MinLength, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMinLengthFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::MaxLength, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseMaxLengthFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::Enumeration, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseEnumerationFacet();
+ enumerationFacets.append(facet);
+ } else if (isSchemaTag(XsdSchemaToken::WhiteSpace, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseWhiteSpaceFacet();
+ addFacet(facet, facets, complexType);
+ } else if (isSchemaTag(XsdSchemaToken::Pattern, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parsePatternFacet();
+ patternFacets.append(facet);
+ } else if (isSchemaTag(XsdSchemaToken::Assertion, token, namespaceToken)) {
+ const XsdFacet::Ptr facet = parseAssertionFacet();
+ assertionFacets.append(facet);
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ // merge all pattern facets into one multi value facet
+ if (!patternFacets.isEmpty()) {
+ const XsdFacet::Ptr patternFacet(new XsdFacet());
+ patternFacet->setType(XsdFacet::Pattern);
+
+ AtomicValue::List multiValue;
+ for (int i = 0; i < patternFacets.count(); ++i)
+ multiValue << patternFacets.at(i)->multiValue();
+
+ patternFacet->setMultiValue(multiValue);
+ addFacet(patternFacet, facets, complexType);
+ }
+
+ // merge all enumeration facets into one multi value facet
+ if (!enumerationFacets.isEmpty()) {
+ const XsdFacet::Ptr enumerationFacet(new XsdFacet());
+ enumerationFacet->setType(XsdFacet::Enumeration);
+
+ AtomicValue::List multiValue;
+ for (int i = 0; i < enumerationFacets.count(); ++i)
+ multiValue << enumerationFacets.at(i)->multiValue();
+
+ enumerationFacet->setMultiValue(multiValue);
+ addFacet(enumerationFacet, facets, complexType);
+ }
+
+ // merge all assertion facets into one facet
+ if (!assertionFacets.isEmpty()) {
+ const XsdFacet::Ptr assertionFacet(new XsdFacet());
+ assertionFacet->setType(XsdFacet::Assertion);
+
+ XsdAssertion::List assertions;
+ for (int i = 0; i < assertionFacets.count(); ++i)
+ assertions << assertionFacets.at(i)->assertions();
+
+ assertionFacet->setAssertions(assertions);
+ addFacet(assertionFacet, facets, complexType);
+ }
+
+ m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation(), facets); // add to resolver
+}
+
+void XsdSchemaParser::parseSimpleContentExtension(const XsdComplexType::Ptr &complexType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Extension, this);
+
+ validateElement(XsdTagScope::SimpleContentExtension);
+
+ complexType->setDerivationMethod(XsdComplexType::DerivationExtension);
+
+ // parse attributes
+ const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "extension");
+ QXmlName typeName;
+ convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver
+
+ validateIdAttribute("extension");
+
+ TagValidationHandler tagValidator(XsdTagScope::SimpleContentExtension, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseComplexContent(const XsdComplexType::Ptr &complexType, bool *mixed)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexContent, this);
+
+ validateElement(XsdTagScope::ComplexContent);
+
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly);
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("mixed"))) {
+ const QString mixedStr = readAttribute(QString::fromLatin1("mixed"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(mixedStr);
+ if (value->hasError()) {
+ attributeContentError("mixed", "complexType", mixedStr, BuiltinTypes::xsBoolean);
+ return;
+ }
+
+ *mixed = value->as<Boolean>()->value();
+ } else {
+ *mixed = false;
+ }
+
+ validateIdAttribute("complexContent");
+
+ TagValidationHandler tagValidator(XsdTagScope::ComplexContent, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) {
+ parseComplexContentRestriction(complexType);
+ } else if (isSchemaTag(XsdSchemaToken::Extension, token, namespaceToken)) {
+ parseComplexContentExtension(complexType);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseComplexContentRestriction(const XsdComplexType::Ptr &complexType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this);
+
+ validateElement(XsdTagScope::ComplexContentRestriction);
+
+ complexType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+
+ // parse attributes
+ const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "restriction");
+ QXmlName typeName;
+ convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver
+
+ validateIdAttribute("restriction");
+
+ TagValidationHandler tagValidator(XsdTagScope::ComplexContentRestriction, this, m_namePool);
+
+ bool hasContent = false;
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
+ const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
+ complexType->contentType()->setOpenContent(openContent);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasContent)
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::Empty);
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseComplexContentExtension(const XsdComplexType::Ptr &complexType)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Extension, this);
+
+ validateElement(XsdTagScope::ComplexContentExtension);
+
+ complexType->setDerivationMethod(XsdComplexType::DerivationExtension);
+
+ // parse attributes
+ const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "extension");
+ QXmlName typeName;
+ convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver
+
+ validateIdAttribute("extension");
+
+ TagValidationHandler tagValidator(XsdTagScope::ComplexContentExtension, this, m_namePool);
+
+ bool hasContent = false;
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ complexType->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) {
+ const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent();
+ complexType->contentType()->setOpenContent(openContent);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalAll(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, complexType);
+ particle->setTerm(term);
+ complexType->contentType()->setParticle(particle);
+ hasContent = true;
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType);
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ complexType->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ complexType->setAttributeWildcard(wildcard);
+ } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) {
+ const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert);
+ complexType->addAssertion(assertion);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasContent)
+ complexType->contentType()->setVariety(XsdComplexType::ContentType::Empty);
+
+ tagValidator.finalize();
+}
+
+
+XsdAssertion::Ptr XsdSchemaParser::parseAssertion(const XsdSchemaToken::NodeName &nodeName, const XsdTagScope::Type &tag)
+{
+ const ElementNamespaceHandler namespaceHandler(nodeName, this);
+
+ validateElement(tag);
+
+ const XsdAssertion::Ptr assertion(new XsdAssertion());
+
+ // parse attributes
+
+ const XsdXPathExpression::Ptr expression = readXPathExpression("assertion");
+ assertion->setTest(expression);
+
+ const QString test = readXPathAttribute(QString::fromLatin1("test"), XPath20, "assertion");
+ expression->setExpression(test);
+
+ validateIdAttribute("assertion");
+
+ TagValidationHandler tagValidator(tag, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ assertion->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return assertion;
+}
+
+XsdComplexType::OpenContent::Ptr XsdSchemaParser::parseOpenContent()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::OpenContent, this);
+
+ validateElement(XsdTagScope::OpenContent);
+
+ const XsdComplexType::OpenContent::Ptr openContent(new XsdComplexType::OpenContent());
+
+ if (hasAttribute(QString::fromLatin1("mode"))) {
+ const QString mode = readAttribute(QString::fromLatin1("mode"));
+
+ if (mode == QString::fromLatin1("none")) {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::None);
+ } else if (mode == QString::fromLatin1("interleave")) {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave);
+ } else if (mode == QString::fromLatin1("suffix")) {
+ m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Suffix);
+ } else {
+ attributeContentError("mode", "openContent", mode);
+ return openContent;
+ }
+ } else {
+ openContent->setMode(XsdComplexType::OpenContent::Interleave);
+ }
+
+ validateIdAttribute("openContent");
+
+ TagValidationHandler tagValidator(XsdTagScope::OpenContent, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ openContent->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle;
+ const XsdWildcard::Ptr wildcard = parseAny(particle);
+ openContent->setWildcard(wildcard);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return openContent;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseNamedGroup()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Group, this);
+
+ validateElement(XsdTagScope::NamedGroup);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ XsdModelGroup::Ptr group;
+
+ QXmlName objectName;
+ if (hasAttribute(QString::fromLatin1("name"))) {
+ objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("group"));
+ }
+
+ validateIdAttribute("group");
+
+ TagValidationHandler tagValidator(XsdTagScope::NamedGroup, this, m_namePool);
+
+ XsdAnnotation::Ptr annotation;
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ annotation = parseAnnotation();
+ } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) {
+ group = parseAll(modelGroup);
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ group = parseChoice(modelGroup);
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ group = parseSequence(modelGroup);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ group->setName(objectName);
+
+ if (annotation)
+ group->addAnnotation(annotation);
+
+ return group;
+}
+
+XsdTerm::Ptr XsdSchemaParser::parseReferredGroup(const XsdParticle::Ptr &particle)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Group, this);
+
+ validateElement(XsdTagScope::ReferredGroup);
+
+ const XsdReference::Ptr reference(new XsdReference());
+ reference->setType(XsdReference::ModelGroup);
+ reference->setSourceLocation(currentSourceLocation());
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "group")) {
+ return reference;
+ }
+
+ const QString value = readQNameAttribute(QString::fromLatin1("ref"), "group");
+ QXmlName referenceName;
+ convertName(value, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
+ reference->setReferenceName(referenceName);
+
+ validateIdAttribute("group");
+
+ TagValidationHandler tagValidator(XsdTagScope::ReferredGroup, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ reference->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return reference;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseAll(const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::All, this);
+
+ validateElement(XsdTagScope::All);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::AllCompositor);
+
+ validateIdAttribute("all");
+
+ TagValidationHandler tagValidator(XsdTagScope::All, this, m_namePool);
+
+ XsdParticle::List particles;
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+
+ if (particle->maximumOccursUnbounded() || particle->maximumOccurs() > 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must be %3 or %4.")
+ .arg(formatAttribute("maxOccurs"))
+ .arg(formatElement("all"))
+ .arg(formatData("0"))
+ .arg(formatData("1")));
+ return modelGroup;
+ }
+
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseLocalAll(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::All, this);
+
+ validateElement(XsdTagScope::LocalAll);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::AllCompositor);
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "all")) {
+ return modelGroup;
+ }
+ if (particle->maximumOccursUnbounded() || particle->maximumOccurs() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3.")
+ .arg(formatAttribute("maxOccurs"))
+ .arg(formatElement("all"))
+ .arg(formatData("1")));
+ return modelGroup;
+ }
+ if (particle->minimumOccurs() != 0 && particle->minimumOccurs() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3 or %4.")
+ .arg(formatAttribute("minOccurs"))
+ .arg(formatElement("all"))
+ .arg(formatData("0"))
+ .arg(formatData("1")));
+ return modelGroup;
+ }
+
+ validateIdAttribute("all");
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalAll, this, m_namePool);
+
+ XsdParticle::List particles;
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+
+ if (particle->maximumOccursUnbounded() || particle->maximumOccurs() > 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3 or %4.")
+ .arg(formatAttribute("maxOccurs"))
+ .arg(formatElement("all"))
+ .arg(formatData("0"))
+ .arg(formatData("1")));
+ return modelGroup;
+ }
+
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseChoice(const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Choice, this);
+
+ validateElement(XsdTagScope::Choice);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::ChoiceCompositor);
+
+ validateIdAttribute("choice");
+
+ XsdParticle::List particles;
+
+ TagValidationHandler tagValidator(XsdTagScope::Choice, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ m_schemaResolver->addAllGroupCheck(term);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseAny(particle);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseLocalChoice(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Choice, this);
+
+ validateElement(XsdTagScope::LocalChoice);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::ChoiceCompositor);
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "choice")) {
+ return modelGroup;
+ }
+
+ validateIdAttribute("choice");
+
+ XsdParticle::List particles;
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalChoice, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ m_schemaResolver->addAllGroupCheck(term);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseAny(particle);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseSequence(const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Sequence, this);
+
+ validateElement(XsdTagScope::Sequence);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
+
+ validateIdAttribute("sequence");
+
+ XsdParticle::List particles;
+
+ TagValidationHandler tagValidator(XsdTagScope::Sequence, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ m_schemaResolver->addAllGroupCheck(term);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseAny(particle);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdModelGroup::Ptr XsdSchemaParser::parseLocalSequence(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Sequence, this);
+
+ validateElement(XsdTagScope::LocalSequence);
+
+ const XsdModelGroup::Ptr modelGroup(new XsdModelGroup());
+ modelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "sequence")) {
+ return modelGroup;
+ }
+
+ validateIdAttribute("sequence");
+
+ XsdParticle::List particles;
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalSequence, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ modelGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalElement(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseReferredGroup(particle);
+ m_schemaResolver->addAllGroupCheck(term);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalChoice(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseLocalSequence(particle, parent);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ const XsdTerm::Ptr term = parseAny(particle);
+ particle->setTerm(term);
+ particles.append(particle);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ modelGroup->setParticles(particles);
+
+ tagValidator.finalize();
+
+ return modelGroup;
+}
+
+XsdAttribute::Ptr XsdSchemaParser::parseGlobalAttribute()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Attribute, this);
+
+ validateElement(XsdTagScope::GlobalAttribute);
+
+ const XsdAttribute::Ptr attribute(new XsdAttribute());
+ attribute->setScope(XsdAttribute::Scope::Ptr(new XsdAttribute::Scope()));
+ attribute->scope()->setVariety(XsdAttribute::Scope::Global);
+
+ if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("attribute"))
+ .arg(formatAttribute("default"))
+ .arg(formatAttribute("fixed")));
+ return attribute;
+ }
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("default"))) {
+ const QString value = readAttribute(QString::fromLatin1("default"));
+ attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint()));
+ attribute->valueConstraint()->setVariety(XsdAttribute::ValueConstraint::Default);
+ attribute->valueConstraint()->setValue(value);
+ } else if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint()));
+ attribute->valueConstraint()->setVariety(XsdAttribute::ValueConstraint::Fixed);
+ attribute->valueConstraint()->setValue(value);
+ }
+
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("attribute"));
+ if ((objectName.namespaceURI() == StandardNamespaces::xsi) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("type")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("nil")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("schemaLocation")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("noNamespaceSchemaLocation"))) {
+
+ error(QtXmlPatterns::tr("Content of %1 attribute of %2 element must not be from namespace %3.")
+ .arg(formatAttribute("name"))
+ .arg(formatElement("attribute"))
+ .arg(formatURI(CommonNamespaces::XSI)));
+ return attribute;
+ }
+ if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must not be %3.")
+ .arg(formatAttribute("name"))
+ .arg(formatElement("attribute"))
+ .arg(formatData("xmlns")));
+ return attribute;
+ }
+ attribute->setName(objectName);
+
+ bool hasTypeAttribute = false;
+ bool hasTypeSpecified = false;
+
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ hasTypeAttribute = true;
+
+ const QString type = readQNameAttribute(QString::fromLatin1("type"), "attribute");
+ QXmlName typeName;
+ convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addAttributeType(attribute, typeName, currentSourceLocation()); // add to resolver
+ hasTypeSpecified = true;
+ }
+
+ validateIdAttribute("attribute");
+
+ TagValidationHandler tagValidator(XsdTagScope::GlobalAttribute, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ attribute->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("attribute"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("type")));
+ break;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(attribute);
+ attribute->setType(type);
+ hasTypeSpecified = true;
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasTypeSpecified) {
+ attribute->setType(BuiltinTypes::xsAnySimpleType); // default value
+ return attribute;
+ }
+
+ tagValidator.finalize();
+
+ return attribute;
+}
+
+XsdAttributeUse::Ptr XsdSchemaParser::parseLocalAttribute(const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Attribute, this);
+
+ validateElement(XsdTagScope::LocalAttribute);
+
+ bool hasRefAttribute = false;
+ bool hasTypeAttribute = false;
+ bool hasTypeSpecified = false;
+
+ XsdAttributeUse::Ptr attributeUse;
+ if (hasAttribute(QString::fromLatin1("ref"))) {
+ const XsdAttributeReference::Ptr reference = XsdAttributeReference::Ptr(new XsdAttributeReference());
+ reference->setType(XsdAttributeReference::AttributeUse);
+ reference->setSourceLocation(currentSourceLocation());
+
+ attributeUse = reference;
+ hasRefAttribute = true;
+ } else {
+ attributeUse = XsdAttributeUse::Ptr(new XsdAttributeUse());
+ }
+
+ if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("attribute"))
+ .arg(formatAttribute("default"))
+ .arg(formatAttribute("fixed")));
+ return attributeUse;
+ }
+
+ if (hasRefAttribute) {
+ if (hasAttribute(QString::fromLatin1("form"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("attribute"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("form")));
+ return attributeUse;
+ }
+ if (hasAttribute(QString::fromLatin1("name"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("attribute"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("name")));
+ return attributeUse;
+ }
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("attribute"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("type")));
+ return attributeUse;
+ }
+ }
+
+ // parse attributes
+
+ // default, fixed and use are handled by both, attribute use and attribute reference
+ if (hasAttribute(QString::fromLatin1("default"))) {
+ const QString value = readAttribute(QString::fromLatin1("default"));
+ attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::Ptr(new XsdAttributeUse::ValueConstraint()));
+ attributeUse->valueConstraint()->setVariety(XsdAttributeUse::ValueConstraint::Default);
+ attributeUse->valueConstraint()->setValue(value);
+ } else if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::Ptr(new XsdAttributeUse::ValueConstraint()));
+ attributeUse->valueConstraint()->setVariety(XsdAttributeUse::ValueConstraint::Fixed);
+ attributeUse->valueConstraint()->setValue(value);
+ }
+
+ if (hasAttribute(QString::fromLatin1("use"))) {
+ const QString value = readAttribute(QString::fromLatin1("use"));
+ if (value != QString::fromLatin1("optional") &&
+ value != QString::fromLatin1("prohibited") &&
+ value != QString::fromLatin1("required")) {
+ attributeContentError("use", "attribute", value);
+ return attributeUse;
+ }
+
+ if (value == QString::fromLatin1("optional"))
+ attributeUse->setUseType(XsdAttributeUse::OptionalUse);
+ else if (value == QString::fromLatin1("prohibited"))
+ attributeUse->setUseType(XsdAttributeUse::ProhibitedUse);
+ else if (value == QString::fromLatin1("required"))
+ attributeUse->setUseType(XsdAttributeUse::RequiredUse);
+
+ if (attributeUse->valueConstraint() && attributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Default && value != QString::fromLatin1("optional")) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must have the value %3 because the %4 attribute is set.")
+ .arg(formatAttribute("use"))
+ .arg(formatElement("attribute"))
+ .arg(formatData("optional"))
+ .arg(formatElement("default")));
+ return attributeUse;
+ }
+ }
+
+ const XsdAttribute::Ptr attribute(new XsdAttribute());
+
+ attributeUse->setAttribute(attribute);
+ m_componentLocationHash.insert(attribute, currentSourceLocation());
+
+ attribute->setScope(XsdAttribute::Scope::Ptr(new XsdAttribute::Scope()));
+ attribute->scope()->setVariety(XsdAttribute::Scope::Local);
+ attribute->scope()->setParent(parent);
+
+ // now make a difference between attribute reference and attribute use
+ if (hasRefAttribute) {
+ const QString reference = readQNameAttribute(QString::fromLatin1("ref"), "attribute");
+ QXmlName referenceName;
+ convertName(reference, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
+
+ const XsdAttributeReference::Ptr attributeReference = attributeUse;
+ attributeReference->setReferenceName(referenceName);
+ } else {
+ if (hasAttribute(QString::fromLatin1("name"))) {
+ const QString attributeName = readNameAttribute("attribute");
+
+ QXmlName objectName;
+ if (hasAttribute(QString::fromLatin1("form"))) {
+ const QString value = readAttribute(QString::fromLatin1("form"));
+ if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
+ attributeContentError("form", "attribute", value);
+ return attributeUse;
+ }
+
+ if (value == QString::fromLatin1("qualified")) {
+ objectName = m_namePool->allocateQName(m_targetNamespace, attributeName);
+ } else {
+ objectName = m_namePool->allocateQName(QString(), attributeName);
+ }
+ } else {
+ if (m_attributeFormDefault == QString::fromLatin1("qualified")) {
+ objectName = m_namePool->allocateQName(m_targetNamespace, attributeName);
+ } else {
+ objectName = m_namePool->allocateQName(QString(), attributeName);
+ }
+ }
+
+ if ((objectName.namespaceURI() == StandardNamespaces::xsi) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("type")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("nil")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("schemaLocation")) &&
+ (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("noNamespaceSchemaLocation"))) {
+
+ error(QtXmlPatterns::tr("Content of %1 attribute of %2 element must not be from namespace %3.")
+ .arg(formatAttribute("name"))
+ .arg(formatElement("attribute"))
+ .arg(formatURI(CommonNamespaces::XSI)));
+ return attributeUse;
+ }
+ if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must not be %3.")
+ .arg(formatAttribute("name"))
+ .arg(formatElement("attribute"))
+ .arg(formatData("xmlns")));
+ return attributeUse;
+ }
+
+ attribute->setName(objectName);
+ }
+
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ hasTypeAttribute = true;
+
+ const QString type = readQNameAttribute(QString::fromLatin1("type"), "attribute");
+ QXmlName typeName;
+ convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addAttributeType(attribute, typeName, currentSourceLocation()); // add to resolver
+ hasTypeSpecified = true;
+ }
+
+ if (attributeUse->valueConstraint()) {
+ //TODO: check whether assigning the value constraint of the attribute use to the attribute is correct
+ if (!attribute->valueConstraint())
+ attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint()));
+
+ attribute->valueConstraint()->setVariety((XsdAttribute::ValueConstraint::Variety)attributeUse->valueConstraint()->variety());
+ attribute->valueConstraint()->setValue(attributeUse->valueConstraint()->value());
+ attribute->valueConstraint()->setLexicalForm(attributeUse->valueConstraint()->lexicalForm());
+ }
+ }
+
+ validateIdAttribute("attribute");
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalAttribute, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ attribute->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("attribute"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("type")));
+ break;
+ }
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("attribute"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("ref")));
+ break;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(attribute);
+ attribute->setType(type);
+ hasTypeSpecified = true;
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ if (!hasTypeSpecified) {
+ attribute->setType(BuiltinTypes::xsAnySimpleType); // default value
+ }
+
+ tagValidator.finalize();
+
+ return attributeUse;
+}
+
+XsdAttributeGroup::Ptr XsdSchemaParser::parseNamedAttributeGroup()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AttributeGroup, this);
+
+ validateElement(XsdTagScope::NamedAttributeGroup);
+
+ const XsdAttributeGroup::Ptr attributeGroup(new XsdAttributeGroup());
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("attributeGroup"));
+ attributeGroup->setName(objectName);
+
+ validateIdAttribute("attributeGroup");
+
+ TagValidationHandler tagValidator(XsdTagScope::NamedAttributeGroup, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ attributeGroup->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(attributeGroup);
+
+ if (attributeUse->useType() == XsdAttributeUse::ProhibitedUse) {
+ warning(QtXmlPatterns::tr("Specifying use='prohibited' inside an attribute group has no effect."));
+ } else {
+ attributeGroup->addAttributeUse(attributeUse);
+ }
+ } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) {
+ const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup();
+ attributeGroup->addAttributeUse(attributeUse);
+ } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) {
+ const XsdWildcard::Ptr wildcard = parseAnyAttribute();
+ attributeGroup->setWildcard(wildcard);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return attributeGroup;
+}
+
+XsdAttributeUse::Ptr XsdSchemaParser::parseReferredAttributeGroup()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AttributeGroup, this);
+
+ validateElement(XsdTagScope::ReferredAttributeGroup);
+
+ const XsdAttributeReference::Ptr attributeReference(new XsdAttributeReference());
+ attributeReference->setType(XsdAttributeReference::AttributeGroup);
+ attributeReference->setSourceLocation(currentSourceLocation());
+
+ // parse attributes
+ const QString reference = readQNameAttribute(QString::fromLatin1("ref"), "attributeGroup");
+ QXmlName referenceName;
+ convertName(reference, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
+ attributeReference->setReferenceName(referenceName);
+
+ validateIdAttribute("attributeGroup");
+
+ TagValidationHandler tagValidator(XsdTagScope::ReferredAttributeGroup, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ attributeReference->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return attributeReference;
+}
+
+XsdElement::Ptr XsdSchemaParser::parseGlobalElement()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Element, this);
+
+ validateElement(XsdTagScope::GlobalElement);
+
+ const XsdElement::Ptr element(new XsdElement());
+ element->setScope(XsdElement::Scope::Ptr(new XsdElement::Scope()));
+ element->scope()->setVariety(XsdElement::Scope::Global);
+
+ bool hasTypeAttribute = false;
+ bool hasTypeSpecified = false;
+ bool hasSubstitutionGroup = false;
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("element"));
+ element->setName(objectName);
+
+ if (hasAttribute(QString::fromLatin1("abstract"))) {
+ const QString abstract = readAttribute(QString::fromLatin1("abstract"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(abstract);
+ if (value->hasError()) {
+ attributeContentError("abstract", "element", abstract, BuiltinTypes::xsBoolean);
+ return element;
+ }
+
+ element->setIsAbstract(value->as<Boolean>()->value());
+ } else {
+ element->setIsAbstract(false); // the default value
+ }
+
+ if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("default"))
+ .arg(formatAttribute("fixed")));
+ return element;
+ }
+
+ if (hasAttribute(QString::fromLatin1("default"))) {
+ const QString value = readAttribute(QString::fromLatin1("default"));
+ element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
+ element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Default);
+ element->valueConstraint()->setValue(value);
+ } else if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
+ element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Fixed);
+ element->valueConstraint()->setValue(value);
+ }
+
+ element->setDisallowedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint | NamedSchemaComponent::SubstitutionConstraint, "element"));
+ element->setSubstitutionGroupExclusions(readDerivationConstraintAttribute(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint, "element"));
+
+ if (hasAttribute(QString::fromLatin1("nillable"))) {
+ const QString nillable = readAttribute(QString::fromLatin1("nillable"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(nillable);
+ if (value->hasError()) {
+ attributeContentError("nillable", "element", nillable, BuiltinTypes::xsBoolean);
+ return element;
+ }
+
+ element->setIsNillable(value->as<Boolean>()->value());
+ } else {
+ element->setIsNillable(false); // the default value
+ }
+
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ const QString type = readQNameAttribute(QString::fromLatin1("type"), "element");
+ QXmlName typeName;
+ convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addElementType(element, typeName, currentSourceLocation()); // add to resolver
+
+ hasTypeAttribute = true;
+ hasTypeSpecified = true;
+ }
+
+ if (hasAttribute(QString::fromLatin1("substitutionGroup"))) {
+ QList<QXmlName> elementNames;
+
+ const QString value = readAttribute(QString::fromLatin1("substitutionGroup"));
+ const QStringList substitutionGroups = value.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ if (substitutionGroups.isEmpty()) {
+ attributeContentError("substitutionGroup", "element", value, BuiltinTypes::xsQName);
+ return element;
+ }
+
+ for (int i = 0; i < substitutionGroups.count(); ++i) {
+ const QString value = substitutionGroups.at(i).simplified();
+ if (!XPathHelper::isQName(value)) {
+ attributeContentError("substitutionGroup", "element", value, BuiltinTypes::xsQName);
+ return element;
+ }
+
+ QXmlName elementName;
+ convertName(value, NamespaceSupport::ElementName, elementName); // translate qualified name into QXmlName
+ elementNames.append(elementName);
+ }
+
+ m_schemaResolver->addSubstitutionGroupAffiliation(element, elementNames, currentSourceLocation()); // add to resolver
+
+ hasSubstitutionGroup = true;
+ }
+
+ validateIdAttribute("element");
+
+ XsdAlternative::List alternatives;
+
+ TagValidationHandler tagValidator(XsdTagScope::GlobalElement, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ element->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("type")));
+ return element;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(element);
+ element->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
+ if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("complexType"))
+ .arg(formatAttribute("type")));
+ return element;
+ }
+
+ const XsdComplexType::Ptr type = parseLocalComplexType();
+ type->setContext(element);
+ element->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::Alternative, token, namespaceToken)) {
+ const XsdAlternative::Ptr alternative = parseAlternative();
+ alternatives.append(alternative);
+ } else if (isSchemaTag(XsdSchemaToken::Unique, token, namespaceToken)) {
+ const XsdIdentityConstraint::Ptr constraint = parseUnique();
+ element->addIdentityConstraint(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Key, token, namespaceToken)) {
+ const XsdIdentityConstraint::Ptr constraint = parseKey();
+ element->addIdentityConstraint(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Keyref, token, namespaceToken)) {
+ const XsdIdentityConstraint::Ptr constraint = parseKeyRef(element);
+ element->addIdentityConstraint(constraint);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ if (!hasTypeSpecified) {
+ if (hasSubstitutionGroup)
+ m_schemaResolver->addSubstitutionGroupType(element);
+ else
+ element->setType(BuiltinTypes::xsAnyType);
+ }
+
+ if (!alternatives.isEmpty()) {
+ element->setTypeTable(XsdElement::TypeTable::Ptr(new XsdElement::TypeTable()));
+
+ for (int i = 0; i < alternatives.count(); ++i) {
+ if (alternatives.at(i)->test())
+ element->typeTable()->addAlternative(alternatives.at(i));
+
+ if (i == (alternatives.count() - 1)) { // the final one
+ if (!alternatives.at(i)->test()) {
+ element->typeTable()->setDefaultTypeDefinition(alternatives.at(i));
+ } else {
+ const XsdAlternative::Ptr alternative(new XsdAlternative());
+ if (element->type())
+ alternative->setType(element->type());
+ else
+ m_schemaResolver->addAlternativeType(alternative, element); // add to resolver
+
+ element->typeTable()->setDefaultTypeDefinition(alternative);
+ }
+ }
+ }
+ }
+
+ return element;
+}
+
+XsdTerm::Ptr XsdSchemaParser::parseLocalElement(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Element, this);
+
+ validateElement(XsdTagScope::LocalElement);
+
+ bool hasRefAttribute = false;
+ bool hasTypeAttribute = false;
+ bool hasTypeSpecified = false;
+
+ XsdTerm::Ptr term;
+ XsdElement::Ptr element;
+ if (hasAttribute(QString::fromLatin1("ref"))) {
+ term = XsdReference::Ptr(new XsdReference());
+ hasRefAttribute = true;
+ } else {
+ term = XsdElement::Ptr(new XsdElement());
+ element = term;
+ }
+
+ if (hasRefAttribute) {
+ if (hasAttribute(QString::fromLatin1("name"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("name")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("block"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("block")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("nillable"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("nillable")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("default"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("default")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("fixed"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("fixed")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("form"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("form")));
+ return term;
+ } else if (hasAttribute(QString::fromLatin1("type"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("ref"))
+ .arg(formatAttribute("type")));
+ return term;
+ }
+ }
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "element")) {
+ return element;
+ }
+
+ if (!hasAttribute(QString::fromLatin1("name")) && !hasAttribute(QString::fromLatin1("ref"))) {
+ error(QtXmlPatterns::tr("%1 element must have either %2 or %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("name"))
+ .arg(formatAttribute("ref")));
+ return element;
+ }
+
+ if (hasRefAttribute) {
+ const QString ref = readQNameAttribute(QString::fromLatin1("ref"), "element");
+ QXmlName referenceName;
+ convertName(ref, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
+
+ const XsdReference::Ptr reference = term;
+ reference->setReferenceName(referenceName);
+ reference->setType(XsdReference::Element);
+ reference->setSourceLocation(currentSourceLocation());
+ } else {
+ element->setScope(XsdElement::Scope::Ptr(new XsdElement::Scope()));
+ element->scope()->setVariety(XsdElement::Scope::Local);
+ element->scope()->setParent(parent);
+
+ if (hasAttribute(QString::fromLatin1("name"))) {
+ const QString elementName = readNameAttribute("element");
+
+ QXmlName objectName;
+ if (hasAttribute(QString::fromLatin1("form"))) {
+ const QString value = readAttribute(QString::fromLatin1("form"));
+ if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) {
+ attributeContentError("form", "element", value);
+ return element;
+ }
+
+ if (value == QString::fromLatin1("qualified")) {
+ objectName = m_namePool->allocateQName(m_targetNamespace, elementName);
+ } else {
+ objectName = m_namePool->allocateQName(QString(), elementName);
+ }
+ } else {
+ if (m_elementFormDefault == QString::fromLatin1("qualified")) {
+ objectName = m_namePool->allocateQName(m_targetNamespace, elementName);
+ } else {
+ objectName = m_namePool->allocateQName(QString(), elementName);
+ }
+ }
+
+ element->setName(objectName);
+ }
+
+ if (hasAttribute(QString::fromLatin1("nillable"))) {
+ const QString nillable = readAttribute(QString::fromLatin1("nillable"));
+
+ const Boolean::Ptr value = Boolean::fromLexical(nillable);
+ if (value->hasError()) {
+ attributeContentError("nillable", "element", nillable, BuiltinTypes::xsBoolean);
+ return term;
+ }
+
+ element->setIsNillable(value->as<Boolean>()->value());
+ } else {
+ element->setIsNillable(false); // the default value
+ }
+
+ if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) {
+ error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together.")
+ .arg(formatElement("element"))
+ .arg(formatAttribute("default"))
+ .arg(formatAttribute("fixed")));
+ return element;
+ }
+
+ if (hasAttribute(QString::fromLatin1("default"))) {
+ const QString value = readAttribute(QString::fromLatin1("default"));
+ element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
+ element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Default);
+ element->valueConstraint()->setValue(value);
+ } else if (hasAttribute(QString::fromLatin1("fixed"))) {
+ const QString value = readAttribute(QString::fromLatin1("fixed"));
+ element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint()));
+ element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Fixed);
+ element->valueConstraint()->setValue(value);
+ }
+
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ const QString type = readQNameAttribute(QString::fromLatin1("type"), "element");
+ QXmlName typeName;
+ convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addElementType(element, typeName, currentSourceLocation()); // add to resolver
+
+ hasTypeAttribute = true;
+ hasTypeSpecified = true;
+ }
+
+ element->setDisallowedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint | NamedSchemaComponent::SubstitutionConstraint, "element"));
+ }
+
+ validateIdAttribute("element");
+
+ XsdAlternative::List alternatives;
+
+ TagValidationHandler tagValidator(XsdTagScope::LocalElement, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ term->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("ref")));
+ return term;
+ } else if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("simpleType"))
+ .arg(formatAttribute("type")));
+ return term;
+ }
+
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ type->setContext(element);
+ element->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("complexType"))
+ .arg(formatAttribute("ref")));
+ return term;
+ } else if (hasTypeAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("complexType"))
+ .arg(formatAttribute("type")));
+ return term;
+ }
+
+ const XsdComplexType::Ptr type = parseLocalComplexType();
+ type->setContext(element);
+ element->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::Alternative, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("alternative"))
+ .arg(formatAttribute("ref")));
+ return term;
+ }
+
+ const XsdAlternative::Ptr alternative = parseAlternative();
+ alternatives.append(alternative);
+ } else if (isSchemaTag(XsdSchemaToken::Unique, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("unique"))
+ .arg(formatAttribute("ref")));
+ return term;
+ }
+
+ const XsdIdentityConstraint::Ptr constraint = parseUnique();
+ element->addIdentityConstraint(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Key, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("key"))
+ .arg(formatAttribute("ref")));
+ return term;
+ }
+
+ const XsdIdentityConstraint::Ptr constraint = parseKey();
+ element->addIdentityConstraint(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Keyref, token, namespaceToken)) {
+ if (hasRefAttribute) {
+ error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.")
+ .arg(formatElement("element"))
+ .arg(formatElement("keyref"))
+ .arg(formatAttribute("ref")));
+ return term;
+ }
+
+ const XsdIdentityConstraint::Ptr constraint = parseKeyRef(element);
+ element->addIdentityConstraint(constraint);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ if (!hasTypeSpecified && !hasRefAttribute)
+ element->setType(BuiltinTypes::xsAnyType);
+
+ if (!hasRefAttribute && !alternatives.isEmpty()) {
+ element->setTypeTable(XsdElement::TypeTable::Ptr(new XsdElement::TypeTable()));
+
+ for (int i = 0; i < alternatives.count(); ++i) {
+ if (alternatives.at(i)->test())
+ element->typeTable()->addAlternative(alternatives.at(i));
+
+ if (i == (alternatives.count() - 1)) { // the final one
+ if (!alternatives.at(i)->test()) {
+ element->typeTable()->setDefaultTypeDefinition(alternatives.at(i));
+ } else {
+ const XsdAlternative::Ptr alternative(new XsdAlternative());
+ if (element->type())
+ alternative->setType(element->type());
+ else
+ m_schemaResolver->addAlternativeType(alternative, element); // add to resolver
+
+ element->typeTable()->setDefaultTypeDefinition(alternative);
+ }
+ }
+ }
+ }
+
+ return term;
+}
+
+XsdIdentityConstraint::Ptr XsdSchemaParser::parseUnique()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Unique, this);
+
+ validateElement(XsdTagScope::Unique);
+
+ const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
+ constraint->setCategory(XsdIdentityConstraint::Unique);
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("unique"));
+ constraint->setName(objectName);
+
+ validateIdAttribute("unique");
+
+ TagValidationHandler tagValidator(XsdTagScope::Unique, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ constraint->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) {
+ parseSelector(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) {
+ parseField(constraint);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ // add constraint to schema for further checking
+ addIdentityConstraint(constraint);
+
+ tagValidator.finalize();
+
+ return constraint;
+}
+
+XsdIdentityConstraint::Ptr XsdSchemaParser::parseKey()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Key, this);
+
+ validateElement(XsdTagScope::Key);
+
+ const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
+ constraint->setCategory(XsdIdentityConstraint::Key);
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("key"));
+ constraint->setName(objectName);
+
+ validateIdAttribute("key");
+
+ TagValidationHandler tagValidator(XsdTagScope::Key, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ constraint->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) {
+ parseSelector(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) {
+ parseField(constraint);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ // add constraint to schema for further checking
+ addIdentityConstraint(constraint);
+
+ tagValidator.finalize();
+
+ return constraint;
+}
+
+XsdIdentityConstraint::Ptr XsdSchemaParser::parseKeyRef(const XsdElement::Ptr &element)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Keyref, this);
+
+ validateElement(XsdTagScope::KeyRef);
+
+ const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint());
+ constraint->setCategory(XsdIdentityConstraint::KeyReference);
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("keyref"));
+ constraint->setName(objectName);
+
+ const QString refer = readQNameAttribute(QString::fromLatin1("refer"), "keyref");
+ QXmlName referenceName;
+ convertName(refer, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName
+ m_schemaResolver->addKeyReference(element, constraint, referenceName, currentSourceLocation()); // add to resolver
+
+ validateIdAttribute("keyref");
+
+ TagValidationHandler tagValidator(XsdTagScope::KeyRef, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ constraint->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) {
+ parseSelector(constraint);
+ } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) {
+ parseField(constraint);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ // add constraint to schema for further checking
+ addIdentityConstraint(constraint);
+
+ tagValidator.finalize();
+
+ return constraint;
+}
+
+void XsdSchemaParser::parseSelector(const XsdIdentityConstraint::Ptr &ptr)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Selector, this);
+
+ validateElement(XsdTagScope::Selector);
+
+ // parse attributes
+ const XsdXPathExpression::Ptr expression = readXPathExpression("selector");
+
+ const QString xpath = readXPathAttribute(QString::fromLatin1("xpath"), XPathSelector, "selector");
+ expression->setExpression(xpath);
+
+ ptr->setSelector(expression);
+
+ validateIdAttribute("selector");
+
+ TagValidationHandler tagValidator(XsdTagScope::Selector, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ expression->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+void XsdSchemaParser::parseField(const XsdIdentityConstraint::Ptr &ptr)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Field, this);
+
+ validateElement(XsdTagScope::Field);
+
+ // parse attributes
+ const XsdXPathExpression::Ptr expression = readXPathExpression("field");
+
+ const QString xpath = readXPathAttribute(QString::fromLatin1("xpath"), XPathField, "field");
+ expression->setExpression(xpath);
+
+ ptr->addField(expression);
+
+ validateIdAttribute("field");
+
+ TagValidationHandler tagValidator(XsdTagScope::Field, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ expression->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+}
+
+XsdAlternative::Ptr XsdSchemaParser::parseAlternative()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Alternative, this);
+
+ validateElement(XsdTagScope::Alternative);
+
+ const XsdAlternative::Ptr alternative(new XsdAlternative());
+
+ bool hasTypeSpecified = false;
+
+ if (hasAttribute(QString::fromLatin1("test"))) {
+ const XsdXPathExpression::Ptr expression = readXPathExpression("alternative");
+
+ const QString test = readXPathAttribute(QString::fromLatin1("test"), XPath20, "alternative");
+ expression->setExpression(test);
+
+ alternative->setTest(expression);
+ }
+
+ if (hasAttribute(QString::fromLatin1("type"))) {
+ const QString type = readQNameAttribute(QString::fromLatin1("type"), "alternative");
+ QXmlName typeName;
+ convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName
+ m_schemaResolver->addAlternativeType(alternative, typeName, currentSourceLocation()); // add to resolver
+
+ hasTypeSpecified = true;
+ }
+
+ validateIdAttribute("alternative");
+
+ TagValidationHandler tagValidator(XsdTagScope::Alternative, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ alternative->addAnnotation(annotation);
+ } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) {
+ const XsdSimpleType::Ptr type = parseLocalSimpleType();
+ alternative->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) {
+ const XsdComplexType::Ptr type = parseLocalComplexType();
+ alternative->setType(type);
+
+ // add it to list of anonymous types as well
+ addAnonymousType(type);
+
+ hasTypeSpecified = true;
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ if (!hasTypeSpecified) {
+ error(QtXmlPatterns::tr("%1 element must have either %2 attribute or %3 or %4 as child element.")
+ .arg(formatElement("alternative"))
+ .arg(formatAttribute("type"))
+ .arg(formatElement("simpleType"))
+ .arg(formatElement("complexType")));
+ return alternative;
+ }
+
+ return alternative;
+}
+
+XsdNotation::Ptr XsdSchemaParser::parseNotation()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Notation, this);
+
+ validateElement(XsdTagScope::Notation);
+
+ const XsdNotation::Ptr notation(new XsdNotation());
+
+ // parse attributes
+ const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("notation"));
+ notation->setName(objectName);
+
+ bool hasOptionalAttribute = false;
+
+ if (hasAttribute(QString::fromLatin1("public"))) {
+ const QString value = readAttribute(QString::fromLatin1("public"));
+ if (!value.isEmpty()) {
+ const DerivedString<TypeToken>::Ptr publicId = DerivedString<TypeToken>::fromLexical(m_namePool, value);
+ if (publicId->hasError()) {
+ attributeContentError("public", "notation", value, BuiltinTypes::xsToken);
+ return notation;
+ }
+ notation->setPublicId(publicId);
+ }
+
+ hasOptionalAttribute = true;
+ }
+
+ if (hasAttribute(QString::fromLatin1("system"))) {
+ const QString value = readAttribute(QString::fromLatin1("system"));
+ if (!isValidUri(value)) {
+ attributeContentError("system", "notation", value, BuiltinTypes::xsAnyURI);
+ return notation;
+ }
+
+ if (!value.isEmpty()) {
+ const AnyURI::Ptr systemId = AnyURI::fromLexical(value);
+ notation->setSystemId(systemId);
+ }
+
+ hasOptionalAttribute = true;
+ }
+
+ if (!hasOptionalAttribute) {
+ error(QtXmlPatterns::tr("%1 element requires either %2 or %3 attribute.")
+ .arg(formatElement("notation"))
+ .arg(formatAttribute("public"))
+ .arg(formatAttribute("system")));
+ return notation;
+ }
+
+ validateIdAttribute("notation");
+
+ TagValidationHandler tagValidator(XsdTagScope::Notation, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isCharacters() || isEntityReference()) {
+ if (!text().toString().trimmed().isEmpty()) {
+ error(QtXmlPatterns::tr("Text or entity references not allowed inside %1 element").arg(formatElement("notation.")));
+ return notation;
+ }
+ }
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ notation->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return notation;
+}
+
+XsdWildcard::Ptr XsdSchemaParser::parseAny(const XsdParticle::Ptr &particle)
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Any, this);
+
+ validateElement(XsdTagScope::Any);
+
+ const XsdWildcard::Ptr wildcard(new XsdWildcard());
+
+ // parse attributes
+ if (!parseMinMaxConstraint(particle, "any")) {
+ return wildcard;
+ }
+
+ if (hasAttribute(QString::fromLatin1("namespace"))) {
+ const QSet<QString> values = readAttribute(QString::fromLatin1("namespace")).split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
+ if ((values.contains(QString::fromLatin1("##any")) || values.contains(QString::fromLatin1("##other"))) && values.count() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must contain %3, %4 or a list of URIs.")
+ .arg(formatAttribute("namespace"))
+ .arg(formatElement("any"))
+ .arg(formatData("##any"))
+ .arg(formatData("##other")));
+ return wildcard;
+ }
+
+ if (values.contains(QString::fromLatin1("##any"))) {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ } else if (values.contains(QString::fromLatin1("##other"))) {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ if (!m_targetNamespace.isEmpty())
+ wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << m_targetNamespace);
+ else
+ wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
+ } else {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ QStringList newValues = values.toList();
+
+ // replace the ##targetNamespace entry
+ for (int i = 0; i < newValues.count(); ++i) {
+ if (newValues.at(i) == QString::fromLatin1("##targetNamespace")) {
+ if (!m_targetNamespace.isEmpty())
+ newValues[i] = m_targetNamespace;
+ else
+ newValues[i] = XsdWildcard::absentNamespace();
+ } else if (newValues.at(i) == QString::fromLatin1("##local")) {
+ newValues[i] = XsdWildcard::absentNamespace();
+ }
+ }
+
+ // check for invalid URIs
+ for (int i = 0; i < newValues.count(); ++i) {
+ const QString stringValue = newValues.at(i);
+ if (stringValue == XsdWildcard::absentNamespace())
+ continue;
+
+ if (!isValidUri(stringValue)) {
+ attributeContentError("namespace", "any", stringValue, BuiltinTypes::xsAnyURI);
+ return wildcard;
+ }
+ }
+
+ wildcard->namespaceConstraint()->setNamespaces(newValues.toSet());
+ }
+ } else {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ }
+
+ if (hasAttribute(QString::fromLatin1("processContents"))) {
+ const QString value = readAttribute(QString::fromLatin1("processContents"));
+ if (value != QString::fromLatin1("lax") &&
+ value != QString::fromLatin1("skip") &&
+ value != QString::fromLatin1("strict")) {
+ attributeContentError("processContents", "any", value);
+ return wildcard;
+ }
+
+ if (value == QString::fromLatin1("lax")) {
+ wildcard->setProcessContents(XsdWildcard::Lax);
+ } else if (value == QString::fromLatin1("skip")) {
+ wildcard->setProcessContents(XsdWildcard::Skip);
+ } else if (value == QString::fromLatin1("strict")) {
+ wildcard->setProcessContents(XsdWildcard::Strict);
+ }
+ } else {
+ wildcard->setProcessContents(XsdWildcard::Strict);
+ }
+
+ validateIdAttribute("any");
+
+ TagValidationHandler tagValidator(XsdTagScope::Any, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ wildcard->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return wildcard;
+}
+
+XsdWildcard::Ptr XsdSchemaParser::parseAnyAttribute()
+{
+ const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AnyAttribute, this);
+
+ validateElement(XsdTagScope::AnyAttribute);
+
+ const XsdWildcard::Ptr wildcard(new XsdWildcard());
+
+ // parse attributes
+ if (hasAttribute(QString::fromLatin1("namespace"))) {
+ const QSet<QString> values = readAttribute(QString::fromLatin1("namespace")).split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
+ if ((values.contains(QString::fromLatin1("##any")) || values.contains(QString::fromLatin1("##other"))) && values.count() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must contain %3, %4 or a list of URIs.")
+ .arg(formatAttribute("namespace"))
+ .arg(formatElement("anyAttribute"))
+ .arg(formatData("##any"))
+ .arg(formatData("##other")));
+ return wildcard;
+ }
+
+ if (values.contains(QString::fromLatin1("##any"))) {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ } else if (values.contains(QString::fromLatin1("##other"))) {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not);
+ if (!m_targetNamespace.isEmpty())
+ wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << m_targetNamespace);
+ else
+ wildcard->namespaceConstraint()->setNamespaces(QSet<QString>() << XsdWildcard::absentNamespace());
+ } else {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration);
+ QStringList newValues = values.toList();
+
+ // replace the ##targetNamespace entry
+ for (int i = 0; i < newValues.count(); ++i) {
+ if (newValues.at(i) == QString::fromLatin1("##targetNamespace")) {
+ if (!m_targetNamespace.isEmpty())
+ newValues[i] = m_targetNamespace;
+ else
+ newValues[i] = XsdWildcard::absentNamespace();
+ } else if (newValues.at(i) == QString::fromLatin1("##local")) {
+ newValues[i] = XsdWildcard::absentNamespace();
+ }
+ }
+
+ // check for invalid URIs
+ for (int i = 0; i < newValues.count(); ++i) {
+ const QString stringValue = newValues.at(i);
+ if (stringValue == XsdWildcard::absentNamespace())
+ continue;
+
+ if (!isValidUri(stringValue)) {
+ attributeContentError("namespace", "anyAttribute", stringValue, BuiltinTypes::xsAnyURI);
+ return wildcard;
+ }
+ }
+
+ wildcard->namespaceConstraint()->setNamespaces(newValues.toSet());
+ }
+ } else {
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ }
+
+ if (hasAttribute(QString::fromLatin1("processContents"))) {
+ const QString value = readAttribute(QString::fromLatin1("processContents"));
+ if (value != QString::fromLatin1("lax") &&
+ value != QString::fromLatin1("skip") &&
+ value != QString::fromLatin1("strict")) {
+ attributeContentError("processContents", "anyAttribute", value);
+ return wildcard;
+ }
+
+ if (value == QString::fromLatin1("lax")) {
+ wildcard->setProcessContents(XsdWildcard::Lax);
+ } else if (value == QString::fromLatin1("skip")) {
+ wildcard->setProcessContents(XsdWildcard::Skip);
+ } else if (value == QString::fromLatin1("strict")) {
+ wildcard->setProcessContents(XsdWildcard::Strict);
+ }
+ } else {
+ wildcard->setProcessContents(XsdWildcard::Strict);
+ }
+
+ validateIdAttribute("anyAttribute");
+
+ TagValidationHandler tagValidator(XsdTagScope::AnyAttribute, this, m_namePool);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name());
+ const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri());
+
+ tagValidator.validate(token);
+
+ if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) {
+ const XsdAnnotation::Ptr annotation = parseAnnotation();
+ wildcard->addAnnotation(annotation);
+ } else {
+ parseUnknown();
+ }
+ }
+ }
+
+ tagValidator.finalize();
+
+ return wildcard;
+}
+
+
+void XsdSchemaParser::parseUnknownDocumentation()
+{
+ Q_ASSERT(isStartElement());
+ m_namespaceSupport.pushContext();
+ m_namespaceSupport.setPrefixes(namespaceDeclarations());
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement())
+ parseUnknownDocumentation();
+ }
+
+ m_namespaceSupport.popContext();
+}
+
+void XsdSchemaParser::parseUnknown()
+{
+ Q_ASSERT(isStartElement());
+ m_namespaceSupport.pushContext();
+ m_namespaceSupport.setPrefixes(namespaceDeclarations());
+
+ error(QtXmlPatterns::tr("%1 element is not allowed in this context.").arg(formatElement(name().toString())));
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement())
+ parseUnknown();
+ }
+
+ m_namespaceSupport.popContext();
+}
+
+bool XsdSchemaParser::parseMinMaxConstraint(const XsdParticle::Ptr &particle, const char *elementName)
+{
+ if (hasAttribute(QString::fromLatin1("minOccurs"))) {
+ const QString value = readAttribute(QString::fromLatin1("minOccurs"));
+
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("minOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger);
+ return false;
+ } else {
+ particle->setMinimumOccurs(integer->as< DerivedInteger<TypeNonNegativeInteger> >()->storedValue());
+ }
+ } else {
+ particle->setMinimumOccurs(1);
+ }
+
+ if (hasAttribute(QString::fromLatin1("maxOccurs"))) {
+ const QString value = readAttribute(QString::fromLatin1("maxOccurs"));
+
+ if (value == QString::fromLatin1("unbounded")) {
+ particle->setMaximumOccursUnbounded(true);
+ } else {
+ particle->setMaximumOccursUnbounded(false);
+ DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value);
+ if (integer->hasError()) {
+ attributeContentError("maxOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger);
+ return false;
+ } else {
+ particle->setMaximumOccurs(integer->as< DerivedInteger<TypeNonNegativeInteger> >()->storedValue());
+ }
+ }
+ } else {
+ particle->setMaximumOccursUnbounded(false);
+ particle->setMaximumOccurs(1);
+ }
+
+ if (!particle->maximumOccursUnbounded()) {
+ if (particle->maximumOccurs() < particle->minimumOccurs()) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element has larger value than %3 attribute.")
+ .arg(formatAttribute("minOccurs"))
+ .arg(formatElement(elementName))
+ .arg(formatAttribute("maxOccurs")));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+QSourceLocation XsdSchemaParser::currentSourceLocation() const
+{
+ QSourceLocation location;
+ location.setLine(lineNumber());
+ location.setColumn(columnNumber());
+ location.setUri(m_documentURI);
+
+ return location;
+}
+
+void XsdSchemaParser::convertName(const QString &qualifiedName, NamespaceSupport::NameType type, QXmlName &name)
+{
+ bool result = m_namespaceSupport.processName(qualifiedName, type, name);
+ if (!result) {
+ error(QtXmlPatterns::tr("Prefix of qualified name %1 is not defined.").arg(formatKeyword(qualifiedName)));
+ }
+}
+
+QString XsdSchemaParser::readNameAttribute(const char *elementName)
+{
+ const QString value = readAttribute(QString::fromLatin1("name")).simplified();
+ if (!QXmlUtils::isNCName(value)) {
+ attributeContentError("name", elementName, value, BuiltinTypes::xsNCName);
+ return QString();
+ } else {
+ return value;
+ }
+}
+
+QString XsdSchemaParser::readQNameAttribute(const QString &typeAttribute, const char *elementName)
+{
+ const QString value = readAttribute(typeAttribute).simplified();
+ if (!XPathHelper::isQName(value)) {
+ attributeContentError(typeAttribute.toLatin1(), elementName, value, BuiltinTypes::xsQName);
+ return QString();
+ } else {
+ return value;
+ }
+}
+
+QString XsdSchemaParser::readNamespaceAttribute(const QString &attributeName, const char *elementName)
+{
+ const QString value = readAttribute(attributeName);
+ if (value.isEmpty()) {
+ attributeContentError(attributeName.toLatin1(), elementName, value, BuiltinTypes::xsAnyURI);
+ return QString();
+ }
+
+ return value;
+}
+
+SchemaType::DerivationConstraints XsdSchemaParser::readDerivationConstraintAttribute(const SchemaType::DerivationConstraints &allowedConstraints, const char *elementName)
+{
+ // first convert the flags into strings for easier comparison
+ QSet<QString> allowedContent;
+ if (allowedConstraints & SchemaType::RestrictionConstraint)
+ allowedContent.insert(QString::fromLatin1("restriction"));
+ if (allowedConstraints & SchemaType::ExtensionConstraint)
+ allowedContent.insert(QString::fromLatin1("extension"));
+ if (allowedConstraints & SchemaType::ListConstraint)
+ allowedContent.insert(QString::fromLatin1("list"));
+ if (allowedConstraints & SchemaType::UnionConstraint)
+ allowedContent.insert(QString::fromLatin1("union"));
+
+ // read content from the attribute if available, otherwise use the default definitions from the schema tag
+ QString content;
+ if (hasAttribute(QString::fromLatin1("final"))) {
+ content = readAttribute(QString::fromLatin1("final"));
+
+ // split string into list to validate the content of the attribute
+ const QStringList values = content.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < values.count(); i++) {
+ const QString value = values.at(i);
+ if (!allowedContent.contains(value) && (value != QString::fromLatin1("#all"))) {
+ attributeContentError("final", elementName, value);
+ return SchemaType::DerivationConstraints();
+ }
+
+ if ((value == QString::fromLatin1("#all")) && values.count() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must either contain %3 or the other values.")
+ .arg(formatAttribute("final"))
+ .arg(formatElement(elementName))
+ .arg(formatData("#all")));
+ return SchemaType::DerivationConstraints();
+ }
+ }
+ } else {
+ // content of the default value has been validated in parseSchema already
+ content = m_finalDefault;
+ }
+
+ QSet<QString> contentSet = content.split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
+
+ // if the '#all' tag is defined, we return all allowed values
+ if (contentSet.contains(QString::fromLatin1("#all"))) {
+ return allowedConstraints;
+ } else { // return the values from content set that intersects with the allowed values
+ contentSet.intersect(allowedContent);
+
+ SchemaType::DerivationConstraints constraints;
+
+ if (contentSet.contains(QString::fromLatin1("restriction")))
+ constraints |= SchemaType::RestrictionConstraint;
+ if (contentSet.contains(QString::fromLatin1("extension")))
+ constraints |= SchemaType::ExtensionConstraint;
+ if (contentSet.contains(QString::fromLatin1("list")))
+ constraints |= SchemaType::ListConstraint;
+ if (contentSet.contains(QString::fromLatin1("union")))
+ constraints |= SchemaType::UnionConstraint;
+
+ return constraints;
+ }
+}
+
+NamedSchemaComponent::BlockingConstraints XsdSchemaParser::readBlockingConstraintAttribute(const NamedSchemaComponent::BlockingConstraints &allowedConstraints, const char *elementName)
+{
+ // first convert the flags into strings for easier comparison
+ QSet<QString> allowedContent;
+ if (allowedConstraints & NamedSchemaComponent::RestrictionConstraint)
+ allowedContent.insert(QString::fromLatin1("restriction"));
+ if (allowedConstraints & NamedSchemaComponent::ExtensionConstraint)
+ allowedContent.insert(QString::fromLatin1("extension"));
+ if (allowedConstraints & NamedSchemaComponent::SubstitutionConstraint)
+ allowedContent.insert(QString::fromLatin1("substitution"));
+
+ // read content from the attribute if available, otherwise use the default definitions from the schema tag
+ QString content;
+ if (hasAttribute(QString::fromLatin1("block"))) {
+ content = readAttribute(QString::fromLatin1("block"));
+
+ // split string into list to validate the content of the attribute
+ const QStringList values = content.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < values.count(); i++) {
+ const QString value = values.at(i);
+ if (!allowedContent.contains(value) && (value != QString::fromLatin1("#all"))) {
+ attributeContentError("block", elementName, value);
+ return NamedSchemaComponent::BlockingConstraints();
+ }
+
+ if ((value == QString::fromLatin1("#all")) && values.count() != 1) {
+ error(QtXmlPatterns::tr("%1 attribute of %2 element must either contain %3 or the other values.")
+ .arg(formatAttribute("block"))
+ .arg(formatElement(elementName))
+ .arg(formatData("#all")));
+ return NamedSchemaComponent::BlockingConstraints();
+ }
+ }
+ } else {
+ // content of the default value has been validated in parseSchema already
+ content = m_blockDefault;
+ }
+
+ QSet<QString> contentSet = content.split(QLatin1Char(' '), QString::SkipEmptyParts).toSet();
+
+ // if the '#all' tag is defined, we return all allowed values
+ if (contentSet.contains(QString::fromLatin1("#all"))) {
+ return allowedConstraints;
+ } else { // return the values from content set that intersects with the allowed values
+ contentSet.intersect(allowedContent);
+
+ NamedSchemaComponent::BlockingConstraints constraints;
+
+ if (contentSet.contains(QString::fromLatin1("restriction")))
+ constraints |= NamedSchemaComponent::RestrictionConstraint;
+ if (contentSet.contains(QString::fromLatin1("extension")))
+ constraints |= NamedSchemaComponent::ExtensionConstraint;
+ if (contentSet.contains(QString::fromLatin1("substitution")))
+ constraints |= NamedSchemaComponent::SubstitutionConstraint;
+
+ return constraints;
+ }
+}
+
+XsdXPathExpression::Ptr XsdSchemaParser::readXPathExpression(const char *elementName)
+{
+ const XsdXPathExpression::Ptr expression(new XsdXPathExpression());
+
+ const QList<QXmlName> namespaceBindings = m_namespaceSupport.namespaceBindings();
+ QXmlName emptyName;
+ for (int i = 0; i < namespaceBindings.count(); ++i) {
+ if (namespaceBindings.at(i).prefix() == StandardPrefixes::empty)
+ emptyName = namespaceBindings.at(i);
+ }
+
+ expression->setNamespaceBindings(namespaceBindings);
+
+ QString xpathDefaultNamespace;
+ if (hasAttribute(QString::fromLatin1("xpathDefaultNamespace"))) {
+ xpathDefaultNamespace = readAttribute(QString::fromLatin1("xpathDefaultNamespace"));
+ if (xpathDefaultNamespace != QString::fromLatin1("##defaultNamespace") &&
+ xpathDefaultNamespace != QString::fromLatin1("##targetNamespace") &&
+ xpathDefaultNamespace != QString::fromLatin1("##local")) {
+ if (!isValidUri(xpathDefaultNamespace)) {
+ attributeContentError("xpathDefaultNamespace", elementName, xpathDefaultNamespace, BuiltinTypes::xsAnyURI);
+ return expression;
+ }
+ }
+ } else {
+ xpathDefaultNamespace = m_xpathDefaultNamespace;
+ }
+
+ AnyURI::Ptr namespaceURI;
+ if (xpathDefaultNamespace == QString::fromLatin1("##defaultNamespace")) {
+ if (!emptyName.isNull())
+ namespaceURI = AnyURI::fromLexical(m_namePool->stringForNamespace(emptyName.namespaceURI()));
+ } else if (xpathDefaultNamespace == QString::fromLatin1("##targetNamespace")) {
+ if (!m_targetNamespace.isEmpty())
+ namespaceURI = AnyURI::fromLexical(m_targetNamespace);
+ } else if (xpathDefaultNamespace == QString::fromLatin1("##local")) {
+ // it is absent
+ } else {
+ namespaceURI = AnyURI::fromLexical(xpathDefaultNamespace);
+ }
+ if (namespaceURI) {
+ if (namespaceURI->hasError()) {
+ attributeContentError("xpathDefaultNamespace", elementName, xpathDefaultNamespace, BuiltinTypes::xsAnyURI);
+ return expression;
+ }
+
+ expression->setDefaultNamespace(namespaceURI);
+ }
+
+ //TODO: read the base uri if qmaintaining reader support it
+
+ return expression;
+}
+
+QString XsdSchemaParser::readXPathAttribute(const QString &attributeName, XPathType type, const char *elementName)
+{
+ const QString value = readAttribute(attributeName);
+ if (value.isEmpty() || value.startsWith(QLatin1Char('/'))) {
+ attributeContentError(attributeName.toLatin1(), elementName, value);
+ return QString();
+ }
+
+ QXmlNamePool namePool(m_namePool.data());
+
+ QXmlQuery::QueryLanguage language = QXmlQuery::XPath20;
+ switch (type) {
+ case XPath20: language = QXmlQuery::XPath20; break;
+ case XPathSelector: language = QXmlQuery::XmlSchema11IdentityConstraintSelector; break;
+ case XPathField: language = QXmlQuery::XmlSchema11IdentityConstraintField; break;
+ };
+
+ QXmlQuery query(language, namePool);
+ QXmlQueryPrivate *queryPrivate = query.d;
+
+ const QList<QXmlName> namespaceBindings = m_namespaceSupport.namespaceBindings();
+ for (int i = 0; i < namespaceBindings.count(); ++i) {
+ if (!namespaceBindings.at(i).prefix() == StandardPrefixes::empty)
+ queryPrivate->addAdditionalNamespaceBinding(namespaceBindings.at(i));
+ }
+
+ query.setQuery(value, m_documentURI);
+ if (!query.isValid()) {
+ attributeContentError(attributeName.toLatin1(), elementName, value);
+ return QString();
+ }
+
+ return value;
+}
+
+void XsdSchemaParser::validateIdAttribute(const char *elementName)
+{
+ if (hasAttribute(QString::fromLatin1("id"))) {
+ const QString value = readAttribute(QString::fromLatin1("id"));
+ DerivedString<TypeID>::Ptr id = DerivedString<TypeID>::fromLexical(m_namePool, value);
+ if (id->hasError()) {
+ attributeContentError("id", elementName, value, BuiltinTypes::xsID);
+ } else {
+ if (m_idCache->hasId(value)) {
+ error(QtXmlPatterns::tr("Component with ID %1 has been defined previously.").arg(formatData(value)));
+ } else {
+ m_idCache->addId(value);
+ }
+ }
+ }
+}
+
+bool XsdSchemaParser::isSchemaTag(XsdSchemaToken::NodeName tag, XsdSchemaToken::NodeName token, XsdSchemaToken::NodeName namespaceToken) const
+{
+ return ((tag == token) && (namespaceToken == XsdSchemaToken::XML_NS_SCHEMA_URI));
+}
+
+void XsdSchemaParser::addElement(const XsdElement::Ptr &element)
+{
+ const QXmlName objectName = element->name(m_namePool);
+ if (m_schema->element(objectName)) {
+ error(QtXmlPatterns::tr("Element %1 already defined.").arg(formatElement(m_namePool->displayName(objectName))));
+ } else {
+ m_schema->addElement(element);
+ m_componentLocationHash.insert(element, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addAttribute(const XsdAttribute::Ptr &attribute)
+{
+ const QXmlName objectName = attribute->name(m_namePool);
+ if (m_schema->attribute(objectName)) {
+ error(QtXmlPatterns::tr("Attribute %1 already defined.").arg(formatAttribute(m_namePool->displayName(objectName))));
+ } else {
+ m_schema->addAttribute(attribute);
+ m_componentLocationHash.insert(attribute, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addType(const SchemaType::Ptr &type)
+{
+ // we don't import redefinitions of builtin types, that just causes problems
+ if (m_builtinTypeNames.contains(type->name(m_namePool)))
+ return;
+
+ const QXmlName objectName = type->name(m_namePool);
+ if (m_schema->type(objectName)) {
+ error(QtXmlPatterns::tr("Type %1 already defined.").arg(formatType(m_namePool, objectName)));
+ } else {
+ m_schema->addType(type);
+ if (type->isSimpleType())
+ m_componentLocationHash.insert(XsdSimpleType::Ptr(type), currentSourceLocation());
+ else
+ m_componentLocationHash.insert(XsdComplexType::Ptr(type), currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addAnonymousType(const SchemaType::Ptr &type)
+{
+ m_schema->addAnonymousType(type);
+ if (type->isSimpleType())
+ m_componentLocationHash.insert(XsdSimpleType::Ptr(type), currentSourceLocation());
+ else
+ m_componentLocationHash.insert(XsdComplexType::Ptr(type), currentSourceLocation());
+}
+
+void XsdSchemaParser::addAttributeGroup(const XsdAttributeGroup::Ptr &group)
+{
+ const QXmlName objectName = group->name(m_namePool);
+ if (m_schema->attributeGroup(objectName)) {
+ error(QtXmlPatterns::tr("Attribute group %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
+ } else {
+ m_schema->addAttributeGroup(group);
+ m_componentLocationHash.insert(group, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addElementGroup(const XsdModelGroup::Ptr &group)
+{
+ const QXmlName objectName = group->name(m_namePool);
+ if (m_schema->elementGroup(objectName)) {
+ error(QtXmlPatterns::tr("Element group %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
+ } else {
+ m_schema->addElementGroup(group);
+ m_componentLocationHash.insert(group, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addNotation(const XsdNotation::Ptr &notation)
+{
+ const QXmlName objectName = notation->name(m_namePool);
+ if (m_schema->notation(objectName)) {
+ error(QtXmlPatterns::tr("Notation %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
+ } else {
+ m_schema->addNotation(notation);
+ m_componentLocationHash.insert(notation, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint)
+{
+ const QXmlName objectName = constraint->name(m_namePool);
+ if (m_schema->identityConstraint(objectName)) {
+ error(QtXmlPatterns::tr("Identity constraint %1 already defined.").arg(formatKeyword(m_namePool, objectName)));
+ } else {
+ m_schema->addIdentityConstraint(constraint);
+ m_componentLocationHash.insert(constraint, currentSourceLocation());
+ }
+}
+
+void XsdSchemaParser::addFacet(const XsdFacet::Ptr &facet, XsdFacet::Hash &facets, const SchemaType::Ptr &type)
+{
+ // @see http://www.w3.org/TR/xmlschema-2/#src-single-facet-value
+ if (facets.contains(facet->type())) {
+ error(QtXmlPatterns::tr("Duplicated facets in simple type %1.").arg(formatType(m_namePool, type)));
+ return;
+ }
+
+ facets.insert(facet->type(), facet);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemaparser_p.h b/src/xmlpatterns/schema/qxsdschemaparser_p.h
new file mode 100644
index 0000000..80d44a5
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaparser_p.h
@@ -0,0 +1,739 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSchemaParser_H
+#define Patternist_XsdSchemaParser_H
+
+#include "qnamespacesupport_p.h"
+#include "qxsdalternative_p.h"
+#include "qxsdattribute_p.h"
+#include "qxsdattributegroup_p.h"
+#include "qxsdattributeterm_p.h"
+#include "qxsdcomplextype_p.h"
+#include "qxsdelement_p.h"
+#include "qxsdidcache_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdnotation_p.h"
+#include "qxsdsimpletype_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdschemaparsercontext_p.h"
+#include "qxsdstatemachine_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+#include <QtCore/QUrl>
+#include <QtXml/QXmlStreamReader>
+#include <QtXmlPatterns/QXmlNamePool>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the parsing of XML schema file.
+ *
+ * This class parses a XML schema in XML presentation from an QIODevice
+ * and returns object representation as XsdSchema.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaParser : public MaintainingReader<XsdSchemaToken, XsdTagScope::Type>
+ {
+ friend class ElementNamespaceHandler;
+ friend class TagValidationHandler;
+
+ public:
+ enum ParserType
+ {
+ TopLevelParser,
+ IncludeParser,
+ ImportParser,
+ RedefineParser
+ };
+
+ /**
+ * Creates a new schema parser object.
+ */
+ XsdSchemaParser(const XsdSchemaContext::Ptr &context, const XsdSchemaParserContext::Ptr &parserContext, QIODevice *device);
+
+ /**
+ * Parses the XML schema file.
+ *
+ * @return @c true on success, @c false if the schema is somehow invalid.
+ */
+ bool parse(ParserType parserType = TopLevelParser);
+
+ /**
+ * Describes a set of namespace URIs
+ */
+ typedef QSet<QUrl> NamespaceSet;
+
+ /**
+ * Adds @p schemas to the list of already included schemas, so the parser
+ * can detect multiple includes of the same schema.
+ */
+ void addIncludedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Sets which @p schemas have been included already, so the parser
+ * can detect multiple includes of the same schema.
+ */
+ void setIncludedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Adds @p schemas to the list of already imported schemas, so the parser
+ * can detect multiple imports of the same schema.
+ */
+ void addImportedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Sets which @p schemas have been imported already, so the parser
+ * can detect circular imports.
+ */
+ void setImportedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Adds @p schemas to the list of already redefined schemas, so the parser
+ * can detect multiple redefines of the same schema.
+ */
+ void addRedefinedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Sets which @p schemas have been redefined already, so the parser
+ * can detect multiple redefines of the same schema.
+ */
+ void setRedefinedSchemas(const NamespaceSet &schemas);
+
+ /**
+ * Sets the target namespace of the schema to parse.
+ */
+ void setTargetNamespace(const QString &targetNamespace);
+
+ /**
+ * Sets the document URI of the schema to parse.
+ */
+ void setDocumentURI(const QUrl &uri);
+
+ /**
+ * Returns the document URI of the schema to parse.
+ */
+ QUrl documentURI() const;
+
+ /**
+ * Reimplemented from MaintainingReader, always returns @c false.
+ */
+ bool isAnyAttributeAllowed() const;
+
+ private:
+ /**
+ * Used internally to report any kind of parsing error or
+ * schema inconsistency.
+ */
+ virtual void error(const QString &msg);
+
+ void attributeContentError(const char *attributeName, const char *elementName, const QString &value, const SchemaType::Ptr &type = SchemaType::Ptr());
+
+ /**
+ * Sets the target namespace of the schema to parse.
+ */
+ void setTargetNamespaceExtended(const QString &targetNamespace);
+
+ /**
+ * This method is called for parsing the top-level <em>schema</em> object.
+ */
+ void parseSchema(ParserType parserType);
+
+ /**
+ * This method is called for parsing any top-level <em>include</em> object.
+ */
+ void parseInclude();
+
+ /**
+ * This method is called for parsing any top-level <em>import</em> object.
+ */
+ void parseImport();
+
+ /**
+ * This method is called for parsing any top-level <em>redefine</em> object.
+ */
+ void parseRedefine();
+
+ /**
+ * This method is called for parsing any <em>annotation</em> object everywhere
+ * in the schema.
+ */
+ XsdAnnotation::Ptr parseAnnotation();
+
+ /**
+ * This method is called for parsing an <em>appinfo</em> object as child of
+ * an <em>annotation</em> object.
+ */
+ XsdApplicationInformation::Ptr parseAppInfo();
+
+ /**
+ * This method is called for parsing a <em>documentation</em> object as child of
+ * an <em>annotation</em> object.
+ */
+ XsdDocumentation::Ptr parseDocumentation();
+
+ /**
+ * This method is called for parsing a <em>defaultOpenContent</em> object.
+ */
+ void parseDefaultOpenContent();
+
+ /**
+ * This method is called for parsing any top-level <em>simpleType</em> object.
+ */
+ XsdSimpleType::Ptr parseGlobalSimpleType();
+
+ /**
+ * This method is called for parsing any <em>simpleType</em> object as descendant
+ * of an <em>element</em> or <em>complexType</em> object.
+ */
+ XsdSimpleType::Ptr parseLocalSimpleType();
+
+ /**
+ * This method is called for parsing a <em>restriction</em> object as child
+ * of a <em>simpleType</em> object.
+ */
+ void parseSimpleRestriction(const XsdSimpleType::Ptr &ptr);
+
+ /**
+ * This method is called for parsing a <em>list</em> object as child
+ * of a <em>simpleType</em> object.
+ */
+ void parseList(const XsdSimpleType::Ptr &ptr);
+
+ /**
+ * This method is called for parsing a <em>union</em> object as child
+ * of a <em>simpleType</em> object.
+ */
+ void parseUnion(const XsdSimpleType::Ptr &ptr);
+
+ /**
+ * This method is called for parsing a <em>minExclusive</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMinExclusiveFacet();
+
+ /**
+ * This method is called for parsing a <em>minInclusive</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMinInclusiveFacet();
+
+ /**
+ * This method is called for parsing a <em>maxExclusive</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMaxExclusiveFacet();
+
+ /**
+ * This method is called for parsing a <em>maxInclusive</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMaxInclusiveFacet();
+
+ /**
+ * This method is called for parsing a <em>totalDigits</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseTotalDigitsFacet();
+
+ /**
+ * This method is called for parsing a <em>fractionDigits</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseFractionDigitsFacet();
+
+ /**
+ * This method is called for parsing a <em>length</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseLengthFacet();
+
+ /**
+ * This method is called for parsing a <em>minLength</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMinLengthFacet();
+
+ /**
+ * This method is called for parsing a <em>maxLength</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseMaxLengthFacet();
+
+ /**
+ * This method is called for parsing an <em>enumeration</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseEnumerationFacet();
+
+ /**
+ * This method is called for parsing a <em>whiteSpace</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseWhiteSpaceFacet();
+
+ /**
+ * This method is called for parsing a <em>pattern</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parsePatternFacet();
+
+ /**
+ * This method is called for parsing an <em>assertion</em> object as child
+ * of a <em>restriction</em> object.
+ */
+ XsdFacet::Ptr parseAssertionFacet();
+
+ /**
+ * This method is called for parsing any top-level <em>complexType</em> object.
+ */
+ XsdComplexType::Ptr parseGlobalComplexType();
+
+ /**
+ * This method is called for parsing any <em>complexType</em> object as descendant
+ * of an <em>element</em> object.
+ */
+ XsdComplexType::Ptr parseLocalComplexType();
+
+ /**
+ * This method resolves the content type of the @p complexType for the given
+ * @p effectiveMixed value.
+ */
+ void resolveComplexContentType(const XsdComplexType::Ptr &complexType, bool effectiveMixed);
+
+ /**
+ * This method is called for parsing a <em>simpleContent</em> object as child
+ * of a <em>complexType</em> object.
+ */
+ void parseSimpleContent(const XsdComplexType::Ptr &complexType);
+
+ /**
+ * This method is called for parsing a <em>restriction</em> object as child
+ * of a <em>simpleContent</em> object.
+ */
+ void parseSimpleContentRestriction(const XsdComplexType::Ptr &complexType);
+
+ /**
+ * This method is called for parsing an <em>extension</em> object as child
+ * of a <em>simpleContent</em> object.
+ */
+ void parseSimpleContentExtension(const XsdComplexType::Ptr &complexType);
+
+ /**
+ * This method is called for parsing a <em>complexContent</em> object as child
+ * of a <em>complexType</em> object.
+ *
+ * @param complexType The complex type the complex content belongs to.
+ * @param mixed The output parameter for the mixed value.
+ */
+ void parseComplexContent(const XsdComplexType::Ptr &complexType, bool *mixed);
+
+ /**
+ * This method is called for parsing a <em>restriction</em> object as child
+ * of a <em>complexContent</em> object.
+ */
+ void parseComplexContentRestriction(const XsdComplexType::Ptr &complexType);
+
+ /**
+ * This method is called for parsing an <em>extension</em> object as child
+ * of a <em>complexContent</em> object.
+ */
+ void parseComplexContentExtension(const XsdComplexType::Ptr &complexType);
+
+ /**
+ * This method is called for parsing an <em>assert</em> object as child
+ * of a <em>complexType</em> or parsing a <em>assertion</em> facet object as
+ * child of a <em>simpleType</em>.
+ *
+ * @param nodeName Either XsdSchemaToken::Assert or XsdSchemaToken::Assertion.
+ * @param tag Either XsdTagScope::Assert or XsdTagScope::Assertion.
+ */
+ XsdAssertion::Ptr parseAssertion(const XsdSchemaToken::NodeName &nodeName, const XsdTagScope::Type &tag);
+
+ /**
+ * This method is called for parsing an <em>openContent</em> object.
+ */
+ XsdComplexType::OpenContent::Ptr parseOpenContent();
+
+ /**
+ * This method is called for parsing a top-level <em>group</em> object.
+ */
+ XsdModelGroup::Ptr parseNamedGroup();
+
+ /**
+ * This method is called for parsing a non-top-level <em>group</em> object
+ * that contains a <em>ref</em> attribute.
+ */
+ XsdTerm::Ptr parseReferredGroup(const XsdParticle::Ptr &particle);
+
+ /**
+ * This method is called for parsing an <em>all</em> object as child
+ * of a top-level <em>group</em> object.
+ *
+ * @param parent The schema component the <em>all</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseAll(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing an <em>all</em> object as descendant
+ * of a <em>complexType</em> object.
+ *
+ * @param particle The particle the <em>all</em> object belongs to.
+ * @param parent The schema component the <em>all</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseLocalAll(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a <em>choice</em> object as child
+ * of a top-level <em>group</em> object.
+ *
+ * @param parent The schema component the <em>choice</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseChoice(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a <em>choice</em> object as descendant
+ * of a <em>complexType</em> object or a <em>choice</em> object.
+ *
+ * @param particle The particle the <em>choice</em> object belongs to.
+ * @param parent The schema component the <em>choice</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseLocalChoice(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a <em>sequence</em> object as child
+ * of a top-level <em>group</em> object.
+ *
+ * @param parent The schema component the <em>sequence</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseSequence(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a <em>sequence</em> object as descendant
+ * of a <em>complexType</em> object or a <em>sequence</em> object.
+ *
+ * @param particle The particle the <em>sequence</em> object belongs to.
+ * @param parent The schema component the <em>sequence</em> object is part of.
+ */
+ XsdModelGroup::Ptr parseLocalSequence(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * A helper method that parses the minOccurs and maxOccurs constraints for
+ * the given @p particle that has the given @p tagName.
+ */
+ bool parseMinMaxConstraint(const XsdParticle::Ptr &particle, const char* tagName);
+
+ /**
+ * This method is called for parsing any top-level <em>attribute</em> object.
+ */
+ XsdAttribute::Ptr parseGlobalAttribute();
+
+ /**
+ * This method is called for parsing any non-top-level <em>attribute</em> object as a
+ * descendant of a <em>complexType</em> object or an <em>attributeGroup</em> object.
+ *
+ * @param parent The parent component the <em>attribute</em> object is part of.
+ */
+ XsdAttributeUse::Ptr parseLocalAttribute(const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a top-level <em>attributeGroup</em> object.
+ */
+ XsdAttributeGroup::Ptr parseNamedAttributeGroup();
+
+ /**
+ * This method is called for parsing a non-top-level <em>attributeGroup</em> object
+ * that contains a <em>ref</em> attribute.
+ */
+ XsdAttributeUse::Ptr parseReferredAttributeGroup();
+
+ /**
+ * This method is called for parsing any top-level <em>element</em> object.
+ */
+ XsdElement::Ptr parseGlobalElement();
+
+ /**
+ * This method is called for parsing any non-top-level <em>element</em> object as a
+ * descendant of a <em>complexType</em> object or a <em>group</em> object.
+ *
+ * @param particle The particle the <em>element</em> object belongs to.
+ * @param parent The parent component the <em>element</em> object is part of.
+ */
+ XsdTerm::Ptr parseLocalElement(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent);
+
+ /**
+ * This method is called for parsing a <em>unique</em> object as child of an <em>element</em> object.
+ */
+ XsdIdentityConstraint::Ptr parseUnique();
+
+ /**
+ * This method is called for parsing a <em>key</em> object as child of an <em>element</em> object.
+ */
+ XsdIdentityConstraint::Ptr parseKey();
+
+ /**
+ * This method is called for parsing a <em>keyref</em> object as child of an <em>element</em> object.
+ */
+ XsdIdentityConstraint::Ptr parseKeyRef(const XsdElement::Ptr &element);
+
+ /**
+ * This method is called for parsing a <em>selector</em> object as child of an <em>unique</em> object,
+ * <em>key</em> object or <em>keyref</em> object,
+ *
+ * @param ptr The identity constraint it belongs to.
+ */
+ void parseSelector(const XsdIdentityConstraint::Ptr &ptr);
+
+ /**
+ * This method is called for parsing a <em>field</em> object as child of an <em>unique</em> object,
+ * <em>key</em> object or <em>keyref</em> object,
+ *
+ * @param ptr The identity constraint it belongs to.
+ */
+ void parseField(const XsdIdentityConstraint::Ptr &ptr);
+
+ /**
+ * This method is called for parsing an <em>alternative</em> object inside an <em>element</em> object.
+ */
+ XsdAlternative::Ptr parseAlternative();
+
+ /**
+ * This method is called for parsing a top-level <em>notation</em> object.
+ */
+ XsdNotation::Ptr parseNotation();
+
+ /**
+ * This method is called for parsing an <em>any</em> object somewhere in
+ * the schema.
+ *
+ * @param particle The particle the <em>any</em> object belongs to.
+ */
+ XsdWildcard::Ptr parseAny(const XsdParticle::Ptr &particle);
+
+ /**
+ * This method is called for parsing an <em>anyAttribute</em> object somewhere in
+ * the schema.
+ */
+ XsdWildcard::Ptr parseAnyAttribute();
+
+ /**
+ * This method is called for parsing unknown object as descendant of the <em>annotation</em> object.
+ */
+ void parseUnknownDocumentation();
+
+ /**
+ * This method is called for parsing unknown object in the schema.
+ */
+ void parseUnknown();
+
+ /**
+ * Returnes an source location for the current position.
+ */
+ QSourceLocation currentSourceLocation() const;
+
+ /**
+ * Converts a @p qualified name into a QXmlName @p name and does some error handling.
+ */
+ void convertName(const QString &qualified, NamespaceSupport::NameType type, QXmlName &name);
+
+ /**
+ * A helper method that reads in a 'name' attribute and checks it for syntactic errors.
+ */
+ inline QString readNameAttribute(const char *elementName);
+
+ /**
+ * A helper method that reads in an attribute that contains an QName and
+ * checks it for syntactic errors.
+ */
+ inline QString readQNameAttribute(const QString &typeAttribute, const char *elementName);
+
+ /**
+ * A helper method that reads in a namespace attribute and checks for syntactic errors.
+ */
+ inline QString readNamespaceAttribute(const QString &attributeName, const char *elementName);
+
+ /**
+ * A helper method that reads the final attribute and does correct handling of schema default definitions.
+ */
+ inline SchemaType::DerivationConstraints readDerivationConstraintAttribute(const SchemaType::DerivationConstraints &allowedConstraints, const char *elementName);
+
+ /**
+ * A helper method that reads the block attribute and does correct handling of schema default definitions.
+ */
+ inline NamedSchemaComponent::BlockingConstraints readBlockingConstraintAttribute(const NamedSchemaComponent::BlockingConstraints &allowedConstraints, const char *elementName);
+
+ /**
+ * A helper method that reads all components for a xpath expression for the current scope.
+ */
+ XsdXPathExpression::Ptr readXPathExpression(const char *elementName);
+
+ /**
+ * Describes the type of XPath that is allowed by the readXPathAttribute method.
+ */
+ enum XPathType {
+ XPath20,
+ XPathSelector,
+ XPathField
+ };
+
+ /**
+ * A helper method that reads an attribute that represents a xpath query and does basic
+ * validation.
+ */
+ QString readXPathAttribute(const QString &attributeName, XPathType type, const char *elementName);
+
+ /**
+ * A helper method that reads in an "id" attribute, checks it for syntactic errors
+ * and tests whether a component with the same id has already been parsed.
+ */
+ inline void validateIdAttribute(const char *elementName);
+
+ /**
+ * Adds an @p element to the schema and checks for duplicated entries.
+ */
+ void addElement(const XsdElement::Ptr &element);
+
+ /**
+ * Adds an @p attribute to the schema and checks for duplicated entries.
+ */
+ void addAttribute(const XsdAttribute::Ptr &attribute);
+
+ /**
+ * Adds a @p type to the schema and checks for duplicated entries.
+ */
+ void addType(const SchemaType::Ptr &type);
+
+ /**
+ * Adds an anonymous @p type to the schema and checks for duplicated entries.
+ */
+ void addAnonymousType(const SchemaType::Ptr &type);
+
+ /**
+ * Adds an attribute @p group to the schema and checks for duplicated entries.
+ */
+ void addAttributeGroup(const XsdAttributeGroup::Ptr &group);
+
+ /**
+ * Adds an element @p group to the schema and checks for duplicated entries.
+ */
+ void addElementGroup(const XsdModelGroup::Ptr &group);
+
+ /**
+ * Adds a @p notation to the schema and checks for duplicated entries.
+ */
+ void addNotation(const XsdNotation::Ptr &notation);
+
+ /**
+ * Adds an identity @p constraint to the schema and checks for duplicated entries.
+ */
+ void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint);
+
+ /**
+ * Adds the @p facet to the list of @p facets for @p type and checks for duplicates.
+ */
+ void addFacet(const XsdFacet::Ptr &facet, XsdFacet::Hash &facets, const SchemaType::Ptr &type);
+
+ /**
+ * Sets up the state machines for validating the right occurrence of xml elements.
+ */
+ void setupStateMachines();
+
+ /**
+ * Sets up a list of names of known builtin types.
+ */
+ void setupBuiltinTypeNames();
+
+ /**
+ * Checks whether the given @p tag is equal to the given @p token and
+ * the given @p namespaceToken is the XML Schema namespace.
+ */
+ inline bool isSchemaTag(XsdSchemaToken::NodeName tag, XsdSchemaToken::NodeName token, XsdSchemaToken::NodeName namespaceToken) const;
+
+ XsdSchemaContext::Ptr m_context;
+ XsdSchemaParserContext::Ptr m_parserContext;
+ NamePool::Ptr m_namePool;
+ NamespaceSupport m_namespaceSupport;
+ XsdSchemaResolver::Ptr m_schemaResolver;
+ XsdSchema::Ptr m_schema;
+
+ QString m_targetNamespace;
+ QString m_attributeFormDefault;
+ QString m_elementFormDefault;
+ QString m_blockDefault;
+ QString m_finalDefault;
+ QString m_xpathDefaultNamespace;
+ QXmlName m_defaultAttributes;
+ XsdComplexType::OpenContent::Ptr m_defaultOpenContent;
+ bool m_defaultOpenContentAppliesToEmpty;
+
+ NamespaceSet m_includedSchemas;
+ NamespaceSet m_importedSchemas;
+ NamespaceSet m_redefinedSchemas;
+ QUrl m_documentURI;
+ XsdIdCache::Ptr m_idCache;
+ QHash<XsdTagScope::Type, XsdStateMachine<XsdSchemaToken::NodeName> > m_stateMachines;
+ ComponentLocationHash m_componentLocationHash;
+ QSet<QXmlName> m_builtinTypeNames;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp b/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp
new file mode 100644
index 0000000..47592b1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp
@@ -0,0 +1,1110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemaparser_p.h"
+
+#include "qbuiltintypes_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/**
+ * @page using_dfa_for_schema Using DFA for validation of correct XML tag occurrence
+ *
+ * This page describes how to use DFAs for validating that the XML child tags of an
+ * XML parent tag occur in the right order.
+ *
+ * To validate the occurrence of XML tags one need a regular expression that describes
+ * which tags can appear how often in what context. For example the regular expression
+ * of the global <em>attribute</em> tag in XML Schema is (annotation?, simpleType?).
+ * That means the <em>attribute</em> tag can contain an <em>annotation</em> tag followed
+ * by a <em>simpleType</em> tag, or just one <em>simpleType</em> tag and even no child
+ * tag at all.
+ * So the regular expression describes some kind of language and all the various occurrences
+ * of the child tags can be seen as words of that language.
+ * We can create a DFA now, that accepts all words (and only these words) of that language
+ * and whenever we want to check if a sequence of child tags belongs to the language,
+ * we test if the sequence passes the DFA successfully.
+ *
+ * The following example shows how to create the DFA for the regular expression method
+ * above.
+ *
+ * \dotfile GlobalAttribute_diagram.dot
+ *
+ * At first we need a start state (1), that's the state the DFA is before it
+ * starts running. As our regular expression allows that there are no child tags, the
+ * start state is an end state as well (marked by the double circle).
+ * Now we fetch the first token from the XML file (let's assume it is an <em>annotation</em> tag)
+ * and check if there is an edge labled with the tag name leaving the current state of the DFA.
+ * If there is no such edge, the input doesn't fullfill the rules of the regular expression,
+ * so we throw an error. Otherwise we follow that edge and the DFA is set to the new state (2) the
+ * edge points to. Now we fetch the next token from the XML file and do the previous steps again.
+ * If there is no further input from the XML file, we check whether the DFA is in an end state and
+ * throw an error if not.
+ *
+ * So the algorithm for checking is quite simple, the whole logic is encoded in the DFA and creating
+ * one for a regular expression is sometimes not easy, however the ones for XML Schema are straight
+ * forward.
+ *
+ * <h2>Legend:</h2>
+ * \dotfile legend.dot
+ * <br>
+ *
+ * <h2>DFA for <em>all</em> tag</h2>
+ * \dotfile All_diagram.dot
+ * <br>
+ * <h2>DFA for <em>alternative</em> tag</h2>
+ * \dotfile Alternative_diagram.dot
+ * <br>
+ * <h2>DFA for <em>annotation</em> tag</h2>
+ * \dotfile Annotation_diagram.dot
+ * <br>
+ * <h2>DFA for <em>anyAttribute</em> tag</h2>
+ * \dotfile AnyAttribute_diagram.dot
+ * <br>
+ * <h2>DFA for <em>any</em> tag</h2>
+ * \dotfile Any_diagram.dot
+ * <br>
+ * <h2>DFA for <em>assert</em> tag</h2>
+ * \dotfile Assert_diagram.dot
+ * <br>
+ * <h2>DFA for <em>choice</em> tag</h2>
+ * \dotfile Choice_diagram.dot
+ * <br>
+ * <h2>DFA for <em>complexContent</em> tag</h2>
+ * \dotfile ComplexContent_diagram.dot
+ * <br>
+ * <h2>DFA for <em>extension</em> tag inside a <em>complexContent</em> tag</h2>
+ * \dotfile ComplexContentExtension_diagram.dot
+ * <br>
+ * <h2>DFA for <em>restriction</em> tag inside a <em>complexContent</em> tag</h2>
+ * \dotfile ComplexContentRestriction_diagram.dot
+ * <br>
+ * <h2>DFA for <em>defaultOpenContent</em> tag</h2>
+ * \dotfile DefaultOpenContent_diagram.dot
+ * <br>
+ * <h2>DFA for <em>enumeration</em> tag</h2>
+ * \dotfile EnumerationFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>field</em> tag</h2>
+ * \dotfile Field_diagram.dot
+ * <br>
+ * <h2>DFA for <em>fractionDigits</em> tag</h2>
+ * \dotfile FractionDigitsFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>attribute</em> tag</h2>
+ * \dotfile GlobalAttribute_diagram.dot
+ * <br>
+ * <h2>DFA for <em>complexType</em> tag</h2>
+ * \dotfile GlobalComplexType_diagram.dot
+ * <br>
+ * <h2>DFA for <em>element</em> tag</h2>
+ * \dotfile GlobalElement_diagram.dot
+ * <br>
+ * <h2>DFA for <em>simpleType</em> tag</h2>
+ * \dotfile GlobalSimpleType_diagram.dot
+ * <br>
+ * <h2>DFA for <em>import</em> tag</h2>
+ * \dotfile Import_diagram.dot
+ * <br>
+ * <h2>DFA for <em>include</em> tag</h2>
+ * \dotfile Include_diagram.dot
+ * <br>
+ * <h2>DFA for <em>key</em> tag</h2>
+ * \dotfile Key_diagram.dot
+ * <br>
+ * <h2>DFA for <em>keyref</em> tag</h2>
+ * \dotfile KeyRef_diagram.dot
+ * <br>
+ * <h2>DFA for <em>length</em> tag</h2>
+ * \dotfile LengthFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>list</em> tag</h2>
+ * \dotfile List_diagram.dot
+ * <br>
+ * <h2>DFA for <em>all</em> tag</h2>
+ * \dotfile LocalAll_diagram.dot
+ * <br>
+ * <h2>DFA for <em>attribute</em> tag</h2>
+ * \dotfile LocalAttribute_diagram.dot
+ * <br>
+ * <h2>DFA for <em>choice</em> tag</h2>
+ * \dotfile LocalChoice_diagram.dot
+ * <br>
+ * <h2>DFA for <em>complexType</em> tag</h2>
+ * \dotfile LocalComplexType_diagram.dot
+ * <br>
+ * <h2>DFA for <em>element</em> tag</h2>
+ * \dotfile LocalElement_diagram.dot
+ * <br>
+ * <h2>DFA for <em>sequence</em> tag</h2>
+ * \dotfile LocalSequence_diagram.dot
+ * <br>
+ * <h2>DFA for <em>simpleType</em> tag that </h2>
+ * \dotfile LocalSimpleType_diagram.dot
+ * <br>
+ * <h2>DFA for <em>maxExclusive</em> tag</h2>
+ * \dotfile MaxExclusiveFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>maxInclusive</em> tag</h2>
+ * \dotfile MaxInclusiveFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>maxLength</em> tag</h2>
+ * \dotfile MaxLengthFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>minExclusive</em> tag</h2>
+ * \dotfile MinExclusiveFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>minInclusive</em> tag</h2>
+ * \dotfile MinInclusiveFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>minLength</em> tag</h2>
+ * \dotfile MinLengthFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>attributeGroup</em> tag without <em>ref</em> attribute</h2>
+ * \dotfile NamedAttributeGroup_diagram.dot
+ * <br>
+ * <h2>DFA for <em>group</em> tag without <em>ref</em> attribute</h2>
+ * \dotfile NamedGroup_diagram.dot
+ * <br>
+ * <h2>DFA for <em>notation</em> tag</h2>
+ * \dotfile Notation_diagram.dot
+ * <br>
+ * <h2>DFA for <em>override</em> tag</h2>
+ * \dotfile Override_diagram.dot
+ * <br>
+ * <h2>DFA for <em>pattern</em> tag</h2>
+ * \dotfile PatternFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>redefine</em> tag</h2>
+ * \dotfile Redefine_diagram.dot
+ * <br>
+ * <h2>DFA for <em>attributeGroup</em> tag with <em>ref</em> attribute</h2>
+ * \dotfile ReferredAttributeGroup_diagram.dot
+ * <br>
+ * <h2>DFA for <em>group</em> tag with <em>ref</em> attribute</h2>
+ * \dotfile ReferredGroup_diagram.dot
+ * <br>
+ * <h2>DFA for <em>schema</em> tag</h2>
+ * \dotfile Schema_diagram.dot
+ * <br>
+ * <h2>DFA for <em>selector</em> tag</h2>
+ * \dotfile Selector_diagram.dot
+ * <br>
+ * <h2>DFA for <em>sequence</em> tag</h2>
+ * \dotfile Sequence_diagram.dot
+ * <br>
+ * <h2>DFA for <em>simpleContent</em> tag</h2>
+ * \dotfile SimpleContent_diagram.dot
+ * <br>
+ * <h2>DFA for <em>extension</em> tag inside a <em>simpleContent</em> tag</h2>
+ * \dotfile SimpleContentExtension_diagram.dot
+ * <br>
+ * <h2>DFA for <em>restriction</em> tag inside a <em>simpleContent</em> tag</h2>
+ * \dotfile SimpleContentRestriction_diagram.dot
+ * <br>
+ * <h2>DFA for <em>restriction</em> tag inside a <em>simpleType</em> tag</h2>
+ * \dotfile SimpleRestriction_diagram.dot
+ * <br>
+ * <h2>DFA for <em>totalDigits</em> tag</h2>
+ * \dotfile TotalDigitsFacet_diagram.dot
+ * <br>
+ * <h2>DFA for <em>union</em> tag</h2>
+ * \dotfile Union_diagram.dot
+ * <br>
+ * <h2>DFA for <em>unique</em> tag</h2>
+ * \dotfile Unique_diagram.dot
+ * <br>
+ * <h2>DFA for <em>whiteSpace</em> tag</h2>
+ * \dotfile WhiteSpaceFacet_diagram.dot
+ */
+
+void XsdSchemaParser::setupStateMachines()
+{
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, simpleType?) : attribute
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+
+ m_stateMachines.insert(XsdTagScope::GlobalAttribute, machine);
+ m_stateMachines.insert(XsdTagScope::LocalAttribute, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, ((simpleType | complexType)?, alternative*, (unique | key | keyref)*)) : element
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(startState, XsdSchemaToken::ComplexType, s2);
+ machine.addTransition(startState, XsdSchemaToken::Alternative, s3);
+ machine.addTransition(startState, XsdSchemaToken::Unique, s4);
+ machine.addTransition(startState, XsdSchemaToken::Key, s4);
+ machine.addTransition(startState, XsdSchemaToken::Keyref, s4);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s1, XsdSchemaToken::ComplexType, s2);
+ machine.addTransition(s1, XsdSchemaToken::Alternative, s3);
+ machine.addTransition(s1, XsdSchemaToken::Unique, s4);
+ machine.addTransition(s1, XsdSchemaToken::Key, s4);
+ machine.addTransition(s1, XsdSchemaToken::Keyref, s4);
+
+ machine.addTransition(s2, XsdSchemaToken::Alternative, s3);
+ machine.addTransition(s2, XsdSchemaToken::Unique, s4);
+ machine.addTransition(s2, XsdSchemaToken::Key, s4);
+ machine.addTransition(s2, XsdSchemaToken::Keyref, s4);
+
+ machine.addTransition(s3, XsdSchemaToken::Alternative, s3);
+ machine.addTransition(s3, XsdSchemaToken::Unique, s4);
+ machine.addTransition(s3, XsdSchemaToken::Key, s4);
+ machine.addTransition(s3, XsdSchemaToken::Keyref, s4);
+
+ machine.addTransition(s4, XsdSchemaToken::Unique, s4);
+ machine.addTransition(s4, XsdSchemaToken::Key, s4);
+ machine.addTransition(s4, XsdSchemaToken::Keyref, s4);
+
+ m_stateMachines.insert(XsdTagScope::GlobalElement, machine);
+ m_stateMachines.insert(XsdTagScope::LocalElement, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (simpleContent | complexContent | (openContent?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*))) : complexType
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s5 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s6 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s7 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleContent, s2);
+ machine.addTransition(startState, XsdSchemaToken::ComplexContent, s2);
+ machine.addTransition(startState, XsdSchemaToken::OpenContent, s3);
+ machine.addTransition(startState, XsdSchemaToken::Group, s4);
+ machine.addTransition(startState, XsdSchemaToken::All, s4);
+ machine.addTransition(startState, XsdSchemaToken::Choice, s4);
+ machine.addTransition(startState, XsdSchemaToken::Sequence, s4);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s5);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s5);
+ machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s6);
+ machine.addTransition(startState, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleContent, s2);
+ machine.addTransition(s1, XsdSchemaToken::ComplexContent, s2);
+ machine.addTransition(s1, XsdSchemaToken::OpenContent, s3);
+ machine.addTransition(s1, XsdSchemaToken::Group, s4);
+ machine.addTransition(s1, XsdSchemaToken::All, s4);
+ machine.addTransition(s1, XsdSchemaToken::Choice, s4);
+ machine.addTransition(s1, XsdSchemaToken::Sequence, s4);
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s5);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s5);
+ machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s6);
+ machine.addTransition(s1, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s3, XsdSchemaToken::Group, s4);
+ machine.addTransition(s3, XsdSchemaToken::All, s4);
+ machine.addTransition(s3, XsdSchemaToken::Choice, s4);
+ machine.addTransition(s3, XsdSchemaToken::Sequence, s4);
+ machine.addTransition(s3, XsdSchemaToken::Attribute, s5);
+ machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s5);
+ machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s6);
+ machine.addTransition(s3, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s4, XsdSchemaToken::Attribute, s5);
+ machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s5);
+ machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s6);
+ machine.addTransition(s4, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s5, XsdSchemaToken::Attribute, s5);
+ machine.addTransition(s5, XsdSchemaToken::AttributeGroup, s5);
+ machine.addTransition(s5, XsdSchemaToken::AnyAttribute, s6);
+ machine.addTransition(s5, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s6, XsdSchemaToken::Assert, s7);
+
+ machine.addTransition(s7, XsdSchemaToken::Assert, s7);
+
+ m_stateMachines.insert(XsdTagScope::GlobalComplexType, machine);
+ m_stateMachines.insert(XsdTagScope::LocalComplexType, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (restriction | extension)) : simpleContent/complexContent
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::InternalState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Restriction, s2);
+ machine.addTransition(startState, XsdSchemaToken::Extension, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Restriction, s2);
+ machine.addTransition(s1, XsdSchemaToken::Extension, s2);
+
+ m_stateMachines.insert(XsdTagScope::SimpleContent, machine);
+ m_stateMachines.insert(XsdTagScope::ComplexContent, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern | assertion)*)?, ((attribute | attributeGroup)*, anyAttribute?), assert*) : simpleContent restriction
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s5 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s6 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(startState, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(startState, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(startState, XsdSchemaToken::Length, s3);
+ machine.addTransition(startState, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(startState, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(startState, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(startState, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(startState, XsdSchemaToken::Assertion, s3);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(startState, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s1, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s1, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s1, XsdSchemaToken::Length, s3);
+ machine.addTransition(s1, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s1, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s1, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s1, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s1, XsdSchemaToken::Assertion, s3);
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s1, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s2, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s2, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s2, XsdSchemaToken::Length, s3);
+ machine.addTransition(s2, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s2, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s2, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s2, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s2, XsdSchemaToken::Assertion, s3);
+ machine.addTransition(s2, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s2, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s3, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s3, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s3, XsdSchemaToken::Length, s3);
+ machine.addTransition(s3, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s3, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s3, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s3, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s3, XsdSchemaToken::Assertion, s3);
+ machine.addTransition(s3, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s3, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s4, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s4, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s5, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s6, XsdSchemaToken::Assert, s6);
+
+ m_stateMachines.insert(XsdTagScope::SimpleContentRestriction, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, ((attribute | attributeGroup)*, anyAttribute?), assert*) : simple content extension
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s3);
+ machine.addTransition(startState, XsdSchemaToken::Assert, s4);
+
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s3);
+ machine.addTransition(s1, XsdSchemaToken::Assert, s4);
+
+ machine.addTransition(s2, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s3);
+ machine.addTransition(s2, XsdSchemaToken::Assert, s4);
+
+ machine.addTransition(s3, XsdSchemaToken::Assert, s4);
+
+ machine.addTransition(s4, XsdSchemaToken::Assert, s4);
+
+ m_stateMachines.insert(XsdTagScope::SimpleContentExtension, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, openContent?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*)) : complex content restriction/complex content extension
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s5 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s6 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::OpenContent, s2);
+ machine.addTransition(startState, XsdSchemaToken::Group, s3);
+ machine.addTransition(startState, XsdSchemaToken::All, s3);
+ machine.addTransition(startState, XsdSchemaToken::Choice, s3);
+ machine.addTransition(startState, XsdSchemaToken::Sequence, s3);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(startState, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s1, XsdSchemaToken::OpenContent, s2);
+ machine.addTransition(s1, XsdSchemaToken::Group, s3);
+ machine.addTransition(s1, XsdSchemaToken::All, s3);
+ machine.addTransition(s1, XsdSchemaToken::Choice, s3);
+ machine.addTransition(s1, XsdSchemaToken::Sequence, s3);
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s1, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s2, XsdSchemaToken::Group, s3);
+ machine.addTransition(s2, XsdSchemaToken::All, s3);
+ machine.addTransition(s2, XsdSchemaToken::Choice, s3);
+ machine.addTransition(s2, XsdSchemaToken::Sequence, s3);
+ machine.addTransition(s2, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s2, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s3, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s3, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s4, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s5);
+ machine.addTransition(s4, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s5, XsdSchemaToken::Assert, s6);
+
+ machine.addTransition(s6, XsdSchemaToken::Assert, s6);
+
+ m_stateMachines.insert(XsdTagScope::ComplexContentRestriction, machine);
+ m_stateMachines.insert(XsdTagScope::ComplexContentExtension, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, ((attribute | attributeGroup)*, anyAttribute?)) : named attribute group
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s3);
+
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s3);
+
+ machine.addTransition(s2, XsdSchemaToken::Attribute, s2);
+ machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s2);
+ machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s3);
+
+ m_stateMachines.insert(XsdTagScope::NamedAttributeGroup, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (all | choice | sequence)?) : group
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::All, s2);
+ machine.addTransition(startState, XsdSchemaToken::Choice, s2);
+ machine.addTransition(startState, XsdSchemaToken::Sequence, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::All, s2);
+ machine.addTransition(s1, XsdSchemaToken::Choice, s2);
+ machine.addTransition(s1, XsdSchemaToken::Sequence, s2);
+
+ m_stateMachines.insert(XsdTagScope::NamedGroup, machine);
+ m_stateMachines.insert(XsdTagScope::ReferredGroup, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (element | any)*) : all
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Element, s2);
+ machine.addTransition(startState, XsdSchemaToken::Any, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Element, s2);
+ machine.addTransition(s1, XsdSchemaToken::Any, s2);
+
+ machine.addTransition(s2, XsdSchemaToken::Element, s2);
+ machine.addTransition(s2, XsdSchemaToken::Any, s2);
+
+ m_stateMachines.insert(XsdTagScope::All, machine);
+ m_stateMachines.insert(XsdTagScope::LocalAll, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (element | group | choice | sequence | any)*) : choice sequence
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Element, s2);
+ machine.addTransition(startState, XsdSchemaToken::Group, s2);
+ machine.addTransition(startState, XsdSchemaToken::Choice, s2);
+ machine.addTransition(startState, XsdSchemaToken::Sequence, s2);
+ machine.addTransition(startState, XsdSchemaToken::Any, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Element, s2);
+ machine.addTransition(s1, XsdSchemaToken::Group, s2);
+ machine.addTransition(s1, XsdSchemaToken::Choice, s2);
+ machine.addTransition(s1, XsdSchemaToken::Sequence, s2);
+ machine.addTransition(s1, XsdSchemaToken::Any, s2);
+
+ machine.addTransition(s2, XsdSchemaToken::Element, s2);
+ machine.addTransition(s2, XsdSchemaToken::Group, s2);
+ machine.addTransition(s2, XsdSchemaToken::Choice, s2);
+ machine.addTransition(s2, XsdSchemaToken::Sequence, s2);
+ machine.addTransition(s2, XsdSchemaToken::Any, s2);
+
+ m_stateMachines.insert(XsdTagScope::Choice, machine);
+ m_stateMachines.insert(XsdTagScope::LocalChoice, machine);
+ m_stateMachines.insert(XsdTagScope::Sequence, machine);
+ m_stateMachines.insert(XsdTagScope::LocalSequence, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?) : any/selector/field/notation/include/import/referred attribute group/anyAttribute/all facets/assert
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+
+ m_stateMachines.insert(XsdTagScope::Any, machine);
+ m_stateMachines.insert(XsdTagScope::Selector, machine);
+ m_stateMachines.insert(XsdTagScope::Field, machine);
+ m_stateMachines.insert(XsdTagScope::Notation, machine);
+ m_stateMachines.insert(XsdTagScope::Include, machine);
+ m_stateMachines.insert(XsdTagScope::Import, machine);
+ m_stateMachines.insert(XsdTagScope::ReferredAttributeGroup, machine);
+ m_stateMachines.insert(XsdTagScope::AnyAttribute, machine);
+ m_stateMachines.insert(XsdTagScope::MinExclusiveFacet, machine);
+ m_stateMachines.insert(XsdTagScope::MinInclusiveFacet, machine);
+ m_stateMachines.insert(XsdTagScope::MaxExclusiveFacet, machine);
+ m_stateMachines.insert(XsdTagScope::MaxInclusiveFacet, machine);
+ m_stateMachines.insert(XsdTagScope::TotalDigitsFacet, machine);
+ m_stateMachines.insert(XsdTagScope::FractionDigitsFacet, machine);
+ m_stateMachines.insert(XsdTagScope::LengthFacet, machine);
+ m_stateMachines.insert(XsdTagScope::MinLengthFacet, machine);
+ m_stateMachines.insert(XsdTagScope::MaxLengthFacet, machine);
+ m_stateMachines.insert(XsdTagScope::EnumerationFacet, machine);
+ m_stateMachines.insert(XsdTagScope::WhiteSpaceFacet, machine);
+ m_stateMachines.insert(XsdTagScope::PatternFacet, machine);
+ m_stateMachines.insert(XsdTagScope::Assert, machine);
+ m_stateMachines.insert(XsdTagScope::Assertion, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (selector, field+)) : unique/key/keyref
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::InternalState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::InternalState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Selector, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Selector, s2);
+ machine.addTransition(s2, XsdSchemaToken::Field, s3);
+ machine.addTransition(s3, XsdSchemaToken::Field, s3);
+
+ m_stateMachines.insert(XsdTagScope::Unique, machine);
+ m_stateMachines.insert(XsdTagScope::Key, machine);
+ m_stateMachines.insert(XsdTagScope::KeyRef, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (simpleType | complexType)?) : alternative
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(startState, XsdSchemaToken::ComplexType, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s1, XsdSchemaToken::ComplexType, s2);
+
+ m_stateMachines.insert(XsdTagScope::Alternative, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (appinfo | documentation)* : annotation
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Appinfo, s1);
+ machine.addTransition(startState, XsdSchemaToken::Documentation, s1);
+
+ machine.addTransition(s1, XsdSchemaToken::Appinfo, s1);
+ machine.addTransition(s1, XsdSchemaToken::Documentation, s1);
+
+ m_stateMachines.insert(XsdTagScope::Annotation, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (restriction | list | union)) : simpleType
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::InternalState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Restriction, s2);
+ machine.addTransition(startState, XsdSchemaToken::List, s2);
+ machine.addTransition(startState, XsdSchemaToken::Union, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Restriction, s2);
+ machine.addTransition(s1, XsdSchemaToken::List, s2);
+ machine.addTransition(s1, XsdSchemaToken::Union, s2);
+
+ m_stateMachines.insert(XsdTagScope::GlobalSimpleType, machine);
+ m_stateMachines.insert(XsdTagScope::LocalSimpleType, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern | assertion)*)) : simple type restriction
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(startState, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(startState, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(startState, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(startState, XsdSchemaToken::Length, s3);
+ machine.addTransition(startState, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(startState, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(startState, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(startState, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(startState, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(startState, XsdSchemaToken::Assertion, s3);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s1, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s1, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s1, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s1, XsdSchemaToken::Length, s3);
+ machine.addTransition(s1, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s1, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s1, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s1, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s1, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s1, XsdSchemaToken::Assertion, s3);
+
+ machine.addTransition(s2, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s2, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s2, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s2, XsdSchemaToken::Length, s3);
+ machine.addTransition(s2, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s2, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s2, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s2, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s2, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s2, XsdSchemaToken::Assertion, s3);
+
+ machine.addTransition(s3, XsdSchemaToken::MinExclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MinInclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxExclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxInclusive, s3);
+ machine.addTransition(s3, XsdSchemaToken::TotalDigits, s3);
+ machine.addTransition(s3, XsdSchemaToken::FractionDigits, s3);
+ machine.addTransition(s3, XsdSchemaToken::Length, s3);
+ machine.addTransition(s3, XsdSchemaToken::MinLength, s3);
+ machine.addTransition(s3, XsdSchemaToken::MaxLength, s3);
+ machine.addTransition(s3, XsdSchemaToken::Enumeration, s3);
+ machine.addTransition(s3, XsdSchemaToken::WhiteSpace, s3);
+ machine.addTransition(s3, XsdSchemaToken::Pattern, s3);
+ machine.addTransition(s3, XsdSchemaToken::Assertion, s3);
+
+ m_stateMachines.insert(XsdTagScope::SimpleRestriction, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, simpleType?) : list
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+
+ m_stateMachines.insert(XsdTagScope::List, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, simpleType*) : union
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s2);
+ machine.addTransition(s2, XsdSchemaToken::SimpleType, s2);
+
+ m_stateMachines.insert(XsdTagScope::Union, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for ((include | import | redefine |i override | annotation)*, (defaultOpenContent, annotation*)?, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*) : schema
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s3 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s4 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s5 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Include, s1);
+ machine.addTransition(startState, XsdSchemaToken::Import, s1);
+ machine.addTransition(startState, XsdSchemaToken::Redefine, s1);
+ machine.addTransition(startState, XsdSchemaToken::Override, s1);
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::DefaultOpenContent, s2);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(startState, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(startState, XsdSchemaToken::Group, s4);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(startState, XsdSchemaToken::Element, s4);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(startState, XsdSchemaToken::Notation, s4);
+
+ machine.addTransition(s1, XsdSchemaToken::Include, s1);
+ machine.addTransition(s1, XsdSchemaToken::Import, s1);
+ machine.addTransition(s1, XsdSchemaToken::Redefine, s1);
+ machine.addTransition(s1, XsdSchemaToken::Override, s1);
+ machine.addTransition(s1, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(s1, XsdSchemaToken::DefaultOpenContent, s2);
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(s1, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(s1, XsdSchemaToken::Group, s4);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s1, XsdSchemaToken::Element, s4);
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s1, XsdSchemaToken::Notation, s4);
+
+ machine.addTransition(s2, XsdSchemaToken::Annotation, s3);
+ machine.addTransition(s2, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(s2, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(s2, XsdSchemaToken::Group, s4);
+ machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s2, XsdSchemaToken::Element, s4);
+ machine.addTransition(s2, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s2, XsdSchemaToken::Notation, s4);
+
+ machine.addTransition(s3, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(s3, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(s3, XsdSchemaToken::Group, s4);
+ machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s3, XsdSchemaToken::Element, s4);
+ machine.addTransition(s3, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s3, XsdSchemaToken::Notation, s4);
+
+ machine.addTransition(s4, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(s4, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(s4, XsdSchemaToken::Group, s4);
+ machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s4, XsdSchemaToken::Element, s4);
+ machine.addTransition(s4, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s4, XsdSchemaToken::Notation, s4);
+ machine.addTransition(s4, XsdSchemaToken::Annotation, s5);
+
+ machine.addTransition(s5, XsdSchemaToken::SimpleType, s4);
+ machine.addTransition(s5, XsdSchemaToken::ComplexType, s4);
+ machine.addTransition(s5, XsdSchemaToken::Group, s4);
+ machine.addTransition(s5, XsdSchemaToken::AttributeGroup, s4);
+ machine.addTransition(s5, XsdSchemaToken::Element, s4);
+ machine.addTransition(s5, XsdSchemaToken::Attribute, s4);
+ machine.addTransition(s5, XsdSchemaToken::Notation, s4);
+ machine.addTransition(s5, XsdSchemaToken::Annotation, s5);
+
+ m_stateMachines.insert(XsdTagScope::Schema, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation?, any) : defaultOpenContent
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::InternalState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s2 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::Any, s2);
+
+ machine.addTransition(s1, XsdSchemaToken::Any, s2);
+
+ m_stateMachines.insert(XsdTagScope::DefaultOpenContent, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation | (simpleType | complexType | group | attributeGroup))* : redefine
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s1);
+ machine.addTransition(startState, XsdSchemaToken::ComplexType, s1);
+ machine.addTransition(startState, XsdSchemaToken::Group, s1);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s1);
+
+ machine.addTransition(s1, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s1);
+ machine.addTransition(s1, XsdSchemaToken::ComplexType, s1);
+ machine.addTransition(s1, XsdSchemaToken::Group, s1);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s1);
+
+ m_stateMachines.insert(XsdTagScope::Redefine, machine);
+ }
+
+ {
+ XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool);
+
+ // setup state machine for (annotation | (simpleType | complexType | group | attributeGroup | element | attribute | notation))* : override
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState);
+ const XsdStateMachine<XsdSchemaToken::NodeName>::StateId s1 = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::EndState);
+
+ machine.addTransition(startState, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(startState, XsdSchemaToken::SimpleType, s1);
+ machine.addTransition(startState, XsdSchemaToken::ComplexType, s1);
+ machine.addTransition(startState, XsdSchemaToken::Group, s1);
+ machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s1);
+ machine.addTransition(startState, XsdSchemaToken::Element, s1);
+ machine.addTransition(startState, XsdSchemaToken::Attribute, s1);
+ machine.addTransition(startState, XsdSchemaToken::Notation, s1);
+
+ machine.addTransition(s1, XsdSchemaToken::Annotation, s1);
+ machine.addTransition(s1, XsdSchemaToken::SimpleType, s1);
+ machine.addTransition(s1, XsdSchemaToken::ComplexType, s1);
+ machine.addTransition(s1, XsdSchemaToken::Group, s1);
+ machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s1);
+ machine.addTransition(s1, XsdSchemaToken::Element, s1);
+ machine.addTransition(s1, XsdSchemaToken::Attribute, s1);
+ machine.addTransition(s1, XsdSchemaToken::Notation, s1);
+
+ m_stateMachines.insert(XsdTagScope::Override, machine);
+ }
+}
+
+void XsdSchemaParser::setupBuiltinTypeNames()
+{
+ m_builtinTypeNames.reserve(48);
+
+ m_builtinTypeNames.insert(BuiltinTypes::xsAnyType->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsAnySimpleType->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUntyped->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsAnyAtomicType->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUntypedAtomic->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDateTime->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDate->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsTime->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDuration->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsYearMonthDuration->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDayTimeDuration->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsFloat->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDouble->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsInteger->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsDecimal->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNonPositiveInteger->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNegativeInteger->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsLong->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsInt->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsShort->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsByte->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNonNegativeInteger->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedLong->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedInt->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedShort->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedByte->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsPositiveInteger->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsGYearMonth->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsGYear->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsGMonthDay->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsGDay->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsGMonth->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsBoolean->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsBase64Binary->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsHexBinary->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsAnyURI->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsQName->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsString->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNormalizedString->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsToken->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsLanguage->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNMTOKEN->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsName->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNCName->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsID->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsIDREF->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsENTITY->name(m_namePool));
+ m_builtinTypeNames.insert(BuiltinTypes::xsNOTATION->name(m_namePool));
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp b/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp
new file mode 100644
index 0000000..381d4d0
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp
@@ -0,0 +1,603 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemaparsercontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaParserContext::XsdSchemaParserContext(const NamePool::Ptr &namePool, const XsdSchemaContext::Ptr &context)
+ : m_namePool(namePool)
+ , m_schema(new XsdSchema(m_namePool))
+ , m_checker(new XsdSchemaChecker(context, this))
+ , m_resolver(new XsdSchemaResolver(context, this))
+ , m_elementDescriptions(setupElementDescriptions())
+{
+}
+
+NamePool::Ptr XsdSchemaParserContext::namePool() const
+{
+ return m_namePool;
+}
+
+XsdSchemaResolver::Ptr XsdSchemaParserContext::resolver() const
+{
+ return m_resolver;
+}
+
+XsdSchemaChecker::Ptr XsdSchemaParserContext::checker() const
+{
+ return m_checker;
+}
+
+XsdSchema::Ptr XsdSchemaParserContext::schema() const
+{
+ return m_schema;
+}
+
+ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash XsdSchemaParserContext::elementDescriptions() const
+{
+ return m_elementDescriptions;
+}
+
+QXmlName XsdSchemaParserContext::createAnonymousName(const QString &targetNamespace) const
+{
+ m_anonymousNameCounter.ref();
+
+ const QString name = QString::fromLatin1("__AnonymousClass_%1").arg((int)m_anonymousNameCounter);
+
+ return m_namePool->allocateQName(targetNamespace, name);
+}
+
+ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash XsdSchemaParserContext::setupElementDescriptions()
+{
+ enum
+ {
+ ReservedForElements = 60
+ };
+
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash elementDescriptions;
+ elementDescriptions.reserve(ReservedForElements);
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Schema];
+ description.optionalAttributes.reserve(10);
+ //description.tagToken = XsdSchemaToken::Schema;
+ description.optionalAttributes.insert(XsdSchemaToken::AttributeFormDefault);
+ description.optionalAttributes.insert(XsdSchemaToken::BlockDefault);
+ description.optionalAttributes.insert(XsdSchemaToken::DefaultAttributes);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ description.optionalAttributes.insert(XsdSchemaToken::ElementFormDefault);
+ description.optionalAttributes.insert(XsdSchemaToken::FinalDefault);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::TargetNamespace);
+ description.optionalAttributes.insert(XsdSchemaToken::Version);
+ description.optionalAttributes.insert(XsdSchemaToken::XmlLanguage);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Include];
+ //description.tagToken = XsdSchemaToken::Include;
+ description.requiredAttributes.insert(XsdSchemaToken::SchemaLocation);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Import];
+ //description.tagToken = XsdSchemaToken::Import;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Namespace);
+ description.optionalAttributes.insert(XsdSchemaToken::SchemaLocation);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Redefine];
+ //description.tagToken = XsdSchemaToken::Redefine;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::SchemaLocation);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Override];
+ //description.tagToken = XsdSchemaToken::Override;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::SchemaLocation);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Annotation];
+ //description.tagToken = XsdSchemaToken::Annotation;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::AppInfo];
+ //description.tagToken = XsdSchemaToken::Appinfo;
+ description.optionalAttributes.insert(XsdSchemaToken::Source);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Documentation];
+ //description.tagToken = XsdSchemaToken::Documentation;
+ description.optionalAttributes.insert(XsdSchemaToken::Source);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::GlobalSimpleType];
+ //description.tagToken = XsdSchemaToken::SimpleType;
+ description.optionalAttributes.insert(XsdSchemaToken::Final);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalSimpleType];
+ //description.tagToken = XsdSchemaToken::SimpleType;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::SimpleRestriction];
+ //description.tagToken = XsdSchemaToken::Restriction;
+ description.optionalAttributes.insert(XsdSchemaToken::Base);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::List];
+ //description.tagToken = XsdSchemaToken::List;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::ItemType);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Union];
+ //description.tagToken = XsdSchemaToken::Union;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MemberTypes);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MinExclusiveFacet];
+ //description.tagToken = XsdSchemaToken::MinExclusive;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MinInclusiveFacet];
+ //description.tagToken = XsdSchemaToken::MinInclusive;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MaxExclusiveFacet];
+ //description.tagToken = XsdSchemaToken::MaxExclusive;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MaxInclusiveFacet];
+ //description.tagToken = XsdSchemaToken::MaxInclusive;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::TotalDigitsFacet];
+ //description.tagToken = XsdSchemaToken::TotalDigits;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::FractionDigitsFacet];
+ //description.tagToken = XsdSchemaToken::FractionDigits;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LengthFacet];
+ //description.tagToken = XsdSchemaToken::Length;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MinLengthFacet];
+ //description.tagToken = XsdSchemaToken::MinLength;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::MaxLengthFacet];
+ //description.tagToken = XsdSchemaToken::MaxLength;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::EnumerationFacet];
+ //description.tagToken = XsdSchemaToken::Enumeration;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::WhiteSpaceFacet];
+ //description.tagToken = XsdSchemaToken::WhiteSpace;
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::PatternFacet];
+ //description.tagToken = XsdSchemaToken::Pattern;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Value);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::GlobalComplexType];
+ description.optionalAttributes.reserve(7);
+ //description.tagToken = XsdSchemaToken::ComplexType;
+ description.optionalAttributes.insert(XsdSchemaToken::Abstract);
+ description.optionalAttributes.insert(XsdSchemaToken::Block);
+ description.optionalAttributes.insert(XsdSchemaToken::DefaultAttributesApply);
+ description.optionalAttributes.insert(XsdSchemaToken::Final);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Mixed);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalComplexType];
+ //description.tagToken = XsdSchemaToken::ComplexType;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Mixed);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::SimpleContent];
+ //description.tagToken = XsdSchemaToken::SimpleContent;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::SimpleContentRestriction];
+ //description.tagToken = XsdSchemaToken::Restriction;
+ description.requiredAttributes.insert(XsdSchemaToken::Base);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::SimpleContentExtension];
+ //description.tagToken = XsdSchemaToken::Extension;
+ description.requiredAttributes.insert(XsdSchemaToken::Base);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::ComplexContent];
+ //description.tagToken = XsdSchemaToken::ComplexContent;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Mixed);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::ComplexContentRestriction];
+ //description.tagToken = XsdSchemaToken::Restriction;
+ description.requiredAttributes.insert(XsdSchemaToken::Base);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::ComplexContentExtension];
+ //description.tagToken = XsdSchemaToken::Extension;
+ description.requiredAttributes.insert(XsdSchemaToken::Base);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::NamedGroup];
+ //description.tagToken = XsdSchemaToken::Group;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::ReferredGroup];
+ description.optionalAttributes.reserve(4);
+ //description.tagToken = XsdSchemaToken::Group;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ description.requiredAttributes.insert(XsdSchemaToken::Ref);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::All];
+ //description.tagToken = XsdSchemaToken::All;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalAll];
+ //description.tagToken = XsdSchemaToken::All;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Choice];
+ //description.tagToken = XsdSchemaToken::Choice;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalChoice];
+ //description.tagToken = XsdSchemaToken::Choice;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Sequence];
+ //description.tagToken = XsdSchemaToken::Sequence;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalSequence];
+ //description.tagToken = XsdSchemaToken::Sequence;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::GlobalAttribute];
+ description.optionalAttributes.reserve(5);
+ //description.tagToken = XsdSchemaToken::Attribute;
+ description.optionalAttributes.insert(XsdSchemaToken::Default);
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ description.optionalAttributes.insert(XsdSchemaToken::Type);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalAttribute];
+ description.optionalAttributes.reserve(8);
+ //description.tagToken = XsdSchemaToken::Attribute;
+ description.optionalAttributes.insert(XsdSchemaToken::Default);
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Form);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Name);
+ description.optionalAttributes.insert(XsdSchemaToken::Ref);
+ description.optionalAttributes.insert(XsdSchemaToken::Type);
+ description.optionalAttributes.insert(XsdSchemaToken::Use);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::NamedAttributeGroup];
+ //description.tagToken = XsdSchemaToken::AttributeGroup;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::ReferredAttributeGroup];
+ //description.tagToken = XsdSchemaToken::AttributeGroup;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Ref);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::LocalElement];
+ description.optionalAttributes.reserve(11);
+ //description.tagToken = XsdSchemaToken::Element;
+ description.optionalAttributes.insert(XsdSchemaToken::Block);
+ description.optionalAttributes.insert(XsdSchemaToken::Default);
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Form);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::Name);
+ description.optionalAttributes.insert(XsdSchemaToken::Nillable);
+ description.optionalAttributes.insert(XsdSchemaToken::Ref);
+ description.optionalAttributes.insert(XsdSchemaToken::Type);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::GlobalElement];
+ description.optionalAttributes.reserve(10);
+ //description.tagToken = XsdSchemaToken::Element;
+ description.optionalAttributes.insert(XsdSchemaToken::Abstract);
+ description.optionalAttributes.insert(XsdSchemaToken::Block);
+ description.optionalAttributes.insert(XsdSchemaToken::Default);
+ description.optionalAttributes.insert(XsdSchemaToken::Final);
+ description.optionalAttributes.insert(XsdSchemaToken::Fixed);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ description.optionalAttributes.insert(XsdSchemaToken::Nillable);
+ description.optionalAttributes.insert(XsdSchemaToken::SubstitutionGroup);
+ description.optionalAttributes.insert(XsdSchemaToken::Type);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Unique];
+ //description.tagToken = XsdSchemaToken::Unique;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Key];
+ //description.tagToken = XsdSchemaToken::Key;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::KeyRef];
+ //description.tagToken = XsdSchemaToken::Keyref;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ description.requiredAttributes.insert(XsdSchemaToken::Refer);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Selector];
+ //description.tagToken = XsdSchemaToken::Selector;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Xpath);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Field];
+ //description.tagToken = XsdSchemaToken::Field;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Xpath);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Notation];
+ description.optionalAttributes.reserve(4);
+ //description.tagToken = XsdSchemaToken::Notation;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Name);
+ description.optionalAttributes.insert(XsdSchemaToken::Public);
+ description.optionalAttributes.insert(XsdSchemaToken::System);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Any];
+ description.optionalAttributes.reserve(7);
+ //description.tagToken = XsdSchemaToken::Any;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::MinOccurs);
+ description.optionalAttributes.insert(XsdSchemaToken::Namespace);
+ description.optionalAttributes.insert(XsdSchemaToken::NotNamespace);
+ description.optionalAttributes.insert(XsdSchemaToken::NotQName);
+ description.optionalAttributes.insert(XsdSchemaToken::ProcessContents);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::AnyAttribute];
+ description.optionalAttributes.reserve(5);
+ //description.tagToken = XsdSchemaToken::AnyAttribute;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Namespace);
+ description.optionalAttributes.insert(XsdSchemaToken::NotNamespace);
+ description.optionalAttributes.insert(XsdSchemaToken::NotQName);
+ description.optionalAttributes.insert(XsdSchemaToken::ProcessContents);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Alternative];
+ //description.tagToken = XsdSchemaToken::Alternative;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Test);
+ description.optionalAttributes.insert(XsdSchemaToken::Type);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::OpenContent];
+ //description.tagToken = XsdSchemaToken::OpenContent;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Mode);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::DefaultOpenContent];
+ //description.tagToken = XsdSchemaToken::DefaultOpenContent;
+ description.optionalAttributes.insert(XsdSchemaToken::AppliesToEmpty);
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.optionalAttributes.insert(XsdSchemaToken::Mode);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Assert];
+ //description.tagToken = XsdSchemaToken::Assert;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Test);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ }
+
+ {
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type> &description = elementDescriptions[XsdTagScope::Assertion];
+ //description.tagToken = XsdSchemaToken::Assertion;
+ description.optionalAttributes.insert(XsdSchemaToken::Id);
+ description.requiredAttributes.insert(XsdSchemaToken::Test);
+ description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace);
+ }
+
+ Q_ASSERT_X(elementDescriptions.count() == ReservedForElements, Q_FUNC_INFO,
+ qPrintable(QString::fromLatin1("Expected is %1, actual is %2.").arg(ReservedForElements).arg(elementDescriptions.count())));
+
+ return elementDescriptions;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h b/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h
new file mode 100644
index 0000000..19c516a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSchemaParserContext_H
+#define Patternist_XsdSchemaParserContext_H
+
+#include "qmaintainingreader_p.h" // for definition of ElementDescription
+#include "qxsdschematoken_p.h"
+#include "qxsdschema_p.h"
+#include "qxsdschemachecker_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdschemaresolver_p.h"
+
+#include <QtCore/QSharedData>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A namespace class that contains identifiers for the different
+ * scopes a tag from the xml schema spec can appear in.
+ */
+ class XsdTagScope
+ {
+ public:
+ enum Type
+ {
+ Schema,
+ Include,
+ Import,
+ Redefine,
+ Annotation,
+ AppInfo,
+ Documentation,
+ GlobalSimpleType,
+ LocalSimpleType,
+ SimpleRestriction,
+ List,
+ Union,
+ MinExclusiveFacet,
+ MinInclusiveFacet,
+ MaxExclusiveFacet,
+ MaxInclusiveFacet,
+ TotalDigitsFacet,
+ FractionDigitsFacet,
+ LengthFacet,
+ MinLengthFacet,
+ MaxLengthFacet,
+ EnumerationFacet,
+ WhiteSpaceFacet,
+ PatternFacet,
+ GlobalComplexType,
+ LocalComplexType,
+ SimpleContent,
+ SimpleContentRestriction,
+ SimpleContentExtension,
+ ComplexContent,
+ ComplexContentRestriction,
+ ComplexContentExtension,
+ NamedGroup,
+ ReferredGroup,
+ All,
+ LocalAll,
+ Choice,
+ LocalChoice,
+ Sequence,
+ LocalSequence,
+ GlobalAttribute,
+ LocalAttribute,
+ NamedAttributeGroup,
+ ReferredAttributeGroup,
+ GlobalElement,
+ LocalElement,
+ Unique,
+ Key,
+ KeyRef,
+ Selector,
+ Field,
+ Notation,
+ Any,
+ AnyAttribute,
+ Alternative,
+ Assert,
+ Assertion,
+ OpenContent,
+ DefaultOpenContent,
+ Override
+ };
+ };
+
+ /**
+ * A hash that keeps the mapping between the single components that can appear
+ * in a schema document (e.g. elements, attributes, type definitions) and their
+ * source locations inside the document.
+ */
+ typedef QHash<NamedSchemaComponent::Ptr, QSourceLocation> ComponentLocationHash;
+
+ /**
+ * @short A context for schema parsing.
+ *
+ * This class provides a context for all components that are
+ * nedded for parsing and compiling the XML schema.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaParserContext : public QSharedData
+ {
+ public:
+ /**
+ * A smart pointer wrapping XsdSchemaParserContext instances.
+ */
+ typedef QExplicitlySharedDataPointer<XsdSchemaParserContext> Ptr;
+
+ /**
+ * Creates a new schema parser context object.
+ *
+ * @param namePool The name pool where all names of the schema will be stored in.
+ * @param context The schema context to use for error reporting etc.
+ */
+ XsdSchemaParserContext(const NamePool::Ptr &namePool, const XsdSchemaContext::Ptr &context);
+
+ /**
+ * Returns the name pool of the schema parser context.
+ */
+ NamePool::Ptr namePool() const;
+
+ /**
+ * Returns the schema resolver of the schema context.
+ */
+ XsdSchemaResolver::Ptr resolver() const;
+
+ /**
+ * Returns the schema resolver of the schema context.
+ */
+ XsdSchemaChecker::Ptr checker() const;
+
+ /**
+ * Returns the schema object of the schema context.
+ */
+ XsdSchema::Ptr schema() const;
+
+ /**
+ * Returns the element descriptions for the schema parser.
+ *
+ * The element descriptions are a fast lookup table for
+ * verifying whether certain attributes are allowed for
+ * a given element type.
+ */
+ ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash elementDescriptions() const;
+
+ /**
+ * Returns an unique name that is used by the schema parser
+ * for anonymous types.
+ *
+ * @param targetNamespace The namespace of the name.
+ */
+ QXmlName createAnonymousName(const QString &targetNamespace) const;
+
+ private:
+ /**
+ * Fills the element description hash with the required and prohibited
+ * attributes.
+ */
+ static ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash setupElementDescriptions();
+
+ NamePool::Ptr m_namePool;
+ XsdSchema::Ptr m_schema;
+ XsdSchemaChecker::Ptr m_checker;
+ XsdSchemaResolver::Ptr m_resolver;
+ const ElementDescription<XsdSchemaToken, XsdTagScope::Type>::Hash m_elementDescriptions;
+ mutable QAtomicInt m_anonymousNameCounter;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschemaresolver.cpp b/src/xmlpatterns/schema/qxsdschemaresolver.cpp
new file mode 100644
index 0000000..f3d1ed0
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaresolver.cpp
@@ -0,0 +1,1743 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschemaresolver_p.h"
+
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qqnamevalue_p.h"
+#include "qxsdattributereference_p.h"
+#include "qxsdparticlechecker_p.h"
+#include "qxsdreference_p.h"
+#include "qxsdschemacontext_p.h"
+#include "qxsdschemahelper_p.h"
+#include "qxsdschemaparsercontext_p.h"
+#include "qxsdschematypesfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaResolver::XsdSchemaResolver(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext)
+ : m_context(context)
+ , m_checker(parserContext->checker())
+ , m_namePool(parserContext->namePool())
+ , m_schema(parserContext->schema())
+{
+ m_keyReferences.reserve(20);
+ m_simpleRestrictionBases.reserve(20);
+ m_simpleListTypes.reserve(20);
+ m_simpleUnionTypes.reserve(20);
+ m_elementTypes.reserve(20);
+ m_complexBaseTypes.reserve(20);
+ m_attributeTypes.reserve(20);
+ m_alternativeTypes.reserve(20);
+ m_alternativeTypeElements.reserve(20);
+ m_substitutionGroupAffiliations.reserve(20);
+
+ m_predefinedSchemaTypes = m_context->schemaTypeFactory()->types().values();
+}
+
+XsdSchemaResolver::~XsdSchemaResolver()
+{
+}
+
+void XsdSchemaResolver::resolve()
+{
+ m_checker->addComponentLocationHash(m_componentLocationHash);
+
+ // resolve the base types for all types
+ resolveSimpleRestrictionBaseTypes();
+ resolveComplexBaseTypes();
+
+ // do the basic checks which depend on having a base type available
+ m_checker->basicCheck();
+
+ // resolve further types that only map a type name to a type object
+ resolveSimpleListType();
+ resolveSimpleUnionTypes();
+ resolveElementTypes();
+ resolveAttributeTypes();
+ resolveAlternativeTypes();
+
+ // resolve objects that do not need information about inheritance
+ resolveKeyReferences();
+ resolveSubstitutionGroupAffiliations();
+
+ // resolve objects that do need information about inheritance
+ resolveSimpleRestrictions();
+ resolveSimpleContentComplexTypes();
+
+ // resolve objects which replace place holders
+ resolveTermReferences();
+ resolveAttributeTermReferences();
+
+ // resolve additional objects that do need information about inheritance
+ resolveAttributeInheritance();
+ resolveComplexContentComplexTypes();
+ resolveSubstitutionGroups();
+
+ resolveEnumerationFacetValues();
+
+ checkRedefinedGroups();
+ checkRedefinedAttributeGroups();
+
+ // check the constraining facets before we resolve them
+ m_checker->checkConstrainingFacets();
+
+ // add it again, as we may have added new components in the meantime
+ m_checker->addComponentLocationHash(m_componentLocationHash);
+
+ m_checker->check();
+}
+
+void XsdSchemaResolver::addKeyReference(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &keyRef, const QXmlName &reference, const QSourceLocation &location)
+{
+ KeyReference item;
+ item.element = element;
+ item.keyRef = keyRef;
+ item.reference = reference;
+ item.location = location;
+
+ m_keyReferences.append(item);
+}
+
+void XsdSchemaResolver::addSimpleRestrictionBase(const XsdSimpleType::Ptr &simpleType, const QXmlName &baseName, const QSourceLocation &location)
+{
+ SimpleRestrictionBase item;
+ item.simpleType = simpleType;
+ item.baseName = baseName;
+ item.location = location;
+
+ m_simpleRestrictionBases.append(item);
+}
+
+void XsdSchemaResolver::removeSimpleRestrictionBase(const XsdSimpleType::Ptr &type)
+{
+ for (int i = 0; i < m_simpleRestrictionBases.count(); ++i) {
+ if (m_simpleRestrictionBases.at(i).simpleType == type) {
+ m_simpleRestrictionBases.remove(i);
+ break;
+ }
+ }
+}
+
+void XsdSchemaResolver::addSimpleListType(const XsdSimpleType::Ptr &simpleType, const QXmlName &typeName, const QSourceLocation &location)
+{
+ SimpleListType item;
+ item.simpleType = simpleType;
+ item.typeName = typeName;
+ item.location = location;
+
+ m_simpleListTypes.append(item);
+}
+
+void XsdSchemaResolver::addSimpleUnionTypes(const XsdSimpleType::Ptr &simpleType, const QList<QXmlName> &typeNames, const QSourceLocation &location)
+{
+ SimpleUnionType item;
+ item.simpleType = simpleType;
+ item.typeNames = typeNames;
+ item.location = location;
+
+ m_simpleUnionTypes.append(item);
+}
+
+void XsdSchemaResolver::addElementType(const XsdElement::Ptr &element, const QXmlName &typeName, const QSourceLocation &location)
+{
+ ElementType item;
+ item.element = element;
+ item.typeName = typeName;
+ item.location = location;
+
+ m_elementTypes.append(item);
+}
+
+void XsdSchemaResolver::addComplexBaseType(const XsdComplexType::Ptr &complexType, const QXmlName &baseName, const QSourceLocation &location, const XsdFacet::Hash &facets)
+{
+ ComplexBaseType item;
+ item.complexType = complexType;
+ item.baseName = baseName;
+ item.location = location;
+ item.facets = facets;
+
+ m_complexBaseTypes.append(item);
+}
+
+void XsdSchemaResolver::removeComplexBaseType(const XsdComplexType::Ptr &type)
+{
+ for (int i = 0; i < m_complexBaseTypes.count(); ++i) {
+ if (m_complexBaseTypes.at(i).complexType == type) {
+ m_complexBaseTypes.remove(i);
+ break;
+ }
+ }
+}
+
+void XsdSchemaResolver::addComplexContentType(const XsdComplexType::Ptr &complexType, const XsdParticle::Ptr &content, bool mixed)
+{
+ ComplexContentType item;
+ item.complexType = complexType;
+ item.explicitContent = content;
+ item.effectiveMixed = mixed;
+ m_complexContentTypes.append(item);
+}
+
+void XsdSchemaResolver::addAttributeType(const XsdAttribute::Ptr &attribute, const QXmlName &typeName, const QSourceLocation &location)
+{
+ AttributeType item;
+ item.attribute = attribute;
+ item.typeName = typeName;
+ item.location = location;
+
+ m_attributeTypes.append(item);
+}
+
+void XsdSchemaResolver::addAlternativeType(const XsdAlternative::Ptr &alternative, const QXmlName &typeName, const QSourceLocation &location)
+{
+ AlternativeType item;
+ item.alternative = alternative;
+ item.typeName = typeName;
+ item.location = location;
+
+ m_alternativeTypes.append(item);
+}
+
+void XsdSchemaResolver::addAlternativeType(const XsdAlternative::Ptr &alternative, const XsdElement::Ptr &element)
+{
+ AlternativeTypeElement item;
+ item.alternative = alternative;
+ item.element = element;
+
+ m_alternativeTypeElements.append(item);
+}
+
+void XsdSchemaResolver::addSubstitutionGroupAffiliation(const XsdElement::Ptr &element, const QList<QXmlName> &elementNames, const QSourceLocation &location)
+{
+ SubstitutionGroupAffiliation item;
+ item.element = element;
+ item.elementNames = elementNames;
+ item.location = location;
+
+ m_substitutionGroupAffiliations.append(item);
+}
+
+void XsdSchemaResolver::addSubstitutionGroupType(const XsdElement::Ptr &element)
+{
+ m_substitutionGroupTypes.append(element);
+}
+
+void XsdSchemaResolver::addComponentLocationHash(const ComponentLocationHash &hash)
+{
+ m_componentLocationHash.unite(hash);
+}
+
+void XsdSchemaResolver::addEnumerationFacetValue(const AtomicValue::Ptr &facetValue, const NamespaceSupport &namespaceSupport)
+{
+ m_enumerationFacetValues.insert(facetValue, namespaceSupport);
+}
+
+void XsdSchemaResolver::addRedefinedGroups(const XsdModelGroup::Ptr &redefinedGroup, const XsdModelGroup::Ptr &group)
+{
+ RedefinedGroups item;
+ item.redefinedGroup = redefinedGroup;
+ item.group = group;
+
+ m_redefinedGroups.append(item);
+}
+
+void XsdSchemaResolver::addRedefinedAttributeGroups(const XsdAttributeGroup::Ptr &redefinedGroup, const XsdAttributeGroup::Ptr &group)
+{
+ RedefinedAttributeGroups item;
+ item.redefinedGroup = redefinedGroup;
+ item.group = group;
+
+ m_redefinedAttributeGroups.append(item);
+}
+
+void XsdSchemaResolver::addAllGroupCheck(const XsdReference::Ptr &reference)
+{
+ m_allGroups.insert(reference);
+}
+
+void XsdSchemaResolver::copyDataTo(const XsdSchemaResolver::Ptr &other) const
+{
+ other->m_keyReferences << m_keyReferences;
+ other->m_simpleRestrictionBases << m_simpleRestrictionBases;
+ other->m_simpleListTypes << m_simpleListTypes;
+ other->m_simpleUnionTypes << m_simpleUnionTypes;
+ other->m_elementTypes << m_elementTypes;
+ other->m_complexBaseTypes << m_complexBaseTypes;
+ other->m_complexContentTypes << m_complexContentTypes;
+ other->m_attributeTypes << m_attributeTypes;
+ other->m_alternativeTypes << m_alternativeTypes;
+ other->m_alternativeTypeElements << m_alternativeTypeElements;
+ other->m_substitutionGroupAffiliations << m_substitutionGroupAffiliations;
+ other->m_substitutionGroupTypes << m_substitutionGroupTypes;
+}
+
+QXmlName XsdSchemaResolver::baseTypeNameOfType(const SchemaType::Ptr &type) const
+{
+ for (int i = 0; i < m_simpleRestrictionBases.count(); ++i) {
+ if (m_simpleRestrictionBases.at(i).simpleType == type)
+ return m_simpleRestrictionBases.at(i).baseName;
+ }
+
+ for (int i = 0; i < m_complexBaseTypes.count(); ++i) {
+ if (m_complexBaseTypes.at(i).complexType == type)
+ return m_complexBaseTypes.at(i).baseName;
+ }
+
+ return QXmlName();
+}
+
+QXmlName XsdSchemaResolver::typeNameOfAttribute(const XsdAttribute::Ptr &attribute) const
+{
+ for (int i = 0; i < m_attributeTypes.count(); ++i) {
+ if (m_attributeTypes.at(i).attribute == attribute)
+ return m_attributeTypes.at(i).typeName;
+ }
+
+ return QXmlName();
+}
+
+void XsdSchemaResolver::setDefaultOpenContent(const XsdComplexType::OpenContent::Ptr &openContent, bool appliesToEmpty)
+{
+ m_defaultOpenContent = openContent;
+ m_defaultOpenContentAppliesToEmpty = appliesToEmpty;
+}
+
+void XsdSchemaResolver::resolveKeyReferences()
+{
+ for (int i = 0; i < m_keyReferences.count(); ++i) {
+ const KeyReference ref = m_keyReferences.at(i);
+
+ const XsdIdentityConstraint::Ptr constraint = m_schema->identityConstraint(ref.reference);
+ if (!constraint) {
+ m_context->error(QtXmlPatterns::tr("%1 references unknown %2 or %3 element %4.")
+ .arg(formatKeyword(ref.keyRef->displayName(m_namePool)))
+ .arg(formatElement("key"))
+ .arg(formatElement("unique"))
+ .arg(formatKeyword(m_namePool, ref.reference)),
+ XsdSchemaContext::XSDError, ref.location);
+ return;
+ }
+
+ if (constraint->category() != XsdIdentityConstraint::Key && constraint->category() != XsdIdentityConstraint::Unique) { // only key and unique can be referenced
+ m_context->error(QtXmlPatterns::tr("%1 references identity constraint %2 that is no %3 or %4 element.")
+ .arg(formatKeyword(ref.keyRef->displayName(m_namePool)))
+ .arg(formatKeyword(m_namePool, ref.reference))
+ .arg(formatElement("key"))
+ .arg(formatElement("unique")),
+ XsdSchemaContext::XSDError, ref.location);
+ return;
+ }
+
+ if (constraint->fields().count() != ref.keyRef->fields().count()) {
+ m_context->error(QtXmlPatterns::tr("%1 has a different number of fields from the identity constraint %2 that it references.")
+ .arg(formatKeyword(ref.keyRef->displayName(m_namePool)))
+ .arg(formatKeyword(m_namePool, ref.reference)),
+ XsdSchemaContext::XSDError, ref.location);
+ return;
+ }
+
+ ref.keyRef->setReferencedKey(constraint);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleRestrictionBaseTypes()
+{
+ // iterate over all simple types that are derived by restriction
+ for (int i = 0; i < m_simpleRestrictionBases.count(); ++i) {
+ const SimpleRestrictionBase item = m_simpleRestrictionBases.at(i);
+
+ // find the base type
+ SchemaType::Ptr type = m_schema->type(item.baseName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.baseName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Base type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, item.baseName))
+ .arg(formatElement("restriction")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ item.simpleType->setWxsSuperType(type);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleRestrictions()
+{
+ XsdSimpleType::List simpleTypes;
+
+ // first collect the global simple types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isSimpleType() && (types.at(i)->derivationMethod() == SchemaType::DerivationRestriction))
+ simpleTypes.append(types.at(i));
+ }
+
+ // then collect all anonymous simple types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (anonymousTypes.at(i)->isSimpleType() && (anonymousTypes.at(i)->derivationMethod() == SchemaType::DerivationRestriction))
+ simpleTypes.append(anonymousTypes.at(i));
+ }
+
+ QSet<XsdSimpleType::Ptr> visitedTypes;
+ for (int i = 0; i < simpleTypes.count(); ++i) {
+ resolveSimpleRestrictions(simpleTypes.at(i), visitedTypes);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleRestrictions(const XsdSimpleType::Ptr &simpleType, QSet<XsdSimpleType::Ptr> &visitedTypes)
+{
+ if (visitedTypes.contains(simpleType))
+ return;
+ else
+ visitedTypes.insert(simpleType);
+
+ if (simpleType->derivationMethod() != XsdSimpleType::DerivationRestriction)
+ return;
+
+ // as xs:NMTOKENS, xs:ENTITIES and xs:IDREFS are provided by our XsdSchemaTypesFactory, they are
+ // setup correctly already and shouldn't be handled here
+ if (m_predefinedSchemaTypes.contains(simpleType))
+ return;
+
+ const SchemaType::Ptr baseType = simpleType->wxsSuperType();
+ Q_ASSERT(baseType);
+
+ if (baseType->isDefinedBySchema())
+ resolveSimpleRestrictions(XsdSimpleType::Ptr(baseType), visitedTypes);
+
+ simpleType->setCategory(baseType->category());
+
+ if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
+ QSet<AnySimpleType::Ptr> visitedPrimitiveTypes;
+ const AnySimpleType::Ptr primitiveType = findPrimitiveType(baseType, visitedPrimitiveTypes);
+ simpleType->setPrimitiveType(primitiveType);
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
+ const XsdSimpleType::Ptr simpleBaseType = baseType;
+ simpleType->setItemType(simpleBaseType->itemType());
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ const XsdSimpleType::Ptr simpleBaseType = baseType;
+ simpleType->setMemberTypes(simpleBaseType->memberTypes());
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleListType()
+{
+ // iterate over all simple types where the item type shall be resolved
+ for (int i = 0; i < m_simpleListTypes.count(); ++i) {
+ const SimpleListType item = m_simpleListTypes.at(i);
+
+ // try to resolve the name
+ SchemaType::Ptr type = m_schema->type(item.typeName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.typeName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Item type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, item.typeName))
+ .arg(formatElement("list")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ item.simpleType->setItemType(type);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleUnionTypes()
+{
+ // iterate over all simple types where the union member types shall be resolved
+ for (int i = 0; i < m_simpleUnionTypes.count(); ++i) {
+ const SimpleUnionType item = m_simpleUnionTypes.at(i);
+
+ AnySimpleType::List memberTypes;
+
+ // iterate over all union member type names
+ const QList<QXmlName> typeNames = item.typeNames;
+ for (int j = 0; j < typeNames.count(); ++j) {
+ const QXmlName typeName = typeNames.at(j);
+
+ // try to resolve the name
+ SchemaType::Ptr type = m_schema->type(typeName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(typeName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Member type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, typeName))
+ .arg(formatElement("union")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ memberTypes.append(type);
+ }
+
+ // append the types that have been defined as <simpleType> children
+ memberTypes << item.simpleType->memberTypes();
+
+ item.simpleType->setMemberTypes(memberTypes);
+ }
+}
+
+void XsdSchemaResolver::resolveElementTypes()
+{
+ for (int i = 0; i < m_elementTypes.count(); ++i) {
+ const ElementType item = m_elementTypes.at(i);
+
+ SchemaType::Ptr type = m_schema->type(item.typeName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.typeName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, item.typeName))
+ .arg(formatElement("element")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ item.element->setType(type);
+ }
+}
+
+void XsdSchemaResolver::resolveComplexBaseTypes()
+{
+ for (int i = 0; i < m_complexBaseTypes.count(); ++i) {
+ const ComplexBaseType item = m_complexBaseTypes.at(i);
+
+ SchemaType::Ptr type = m_schema->type(item.baseName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.baseName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Base type %1 of complex type cannot be resolved.").arg(formatType(m_namePool, item.baseName)), XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ if (item.complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (type->isComplexType() && type->isDefinedBySchema()) {
+ const XsdComplexType::Ptr baseType = type;
+ if (baseType->contentType()->variety() != XsdComplexType::ContentType::Simple) {
+ m_context->error(QtXmlPatterns::tr("%1 cannot have complex base type that has a %2.")
+ .arg(formatElement("simpleContent"))
+ .arg(formatElement("complexContent")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+ }
+
+ item.complexType->setWxsSuperType(type);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleContentComplexTypes()
+{
+ XsdComplexType::List complexTypes;
+
+ // first collect the global complex types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema())
+ complexTypes.append(types.at(i));
+ }
+
+ // then collect all anonymous simple types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (anonymousTypes.at(i)->isComplexType() && anonymousTypes.at(i)->isDefinedBySchema())
+ complexTypes.append(anonymousTypes.at(i));
+ }
+
+ QSet<XsdComplexType::Ptr> visitedTypes;
+ for (int i = 0; i < complexTypes.count(); ++i) {
+ if (XsdComplexType::Ptr(complexTypes.at(i))->contentType()->variety() == XsdComplexType::ContentType::Simple)
+ resolveSimpleContentComplexTypes(complexTypes.at(i), visitedTypes);
+ }
+}
+
+void XsdSchemaResolver::resolveSimpleContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes)
+{
+ if (visitedTypes.contains(complexType))
+ return;
+ else
+ visitedTypes.insert(complexType);
+
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+
+ // at this point simple types have been resolved already, so we care about
+ // complex types here only
+
+ // http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctsc
+ // 1
+ if (baseType->isComplexType() && baseType->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexBaseType = baseType;
+
+ resolveSimpleContentComplexTypes(complexBaseType, visitedTypes);
+
+ if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) {
+ if (complexType->contentType()->simpleType()) {
+ // 1.1 contains the content of the <simpleType> already
+ } else {
+ // 1.2
+ const XsdSimpleType::Ptr anonType(new XsdSimpleType());
+ XsdSimpleType::TypeCategory baseCategory = complexBaseType->contentType()->simpleType()->category();
+ anonType->setCategory(baseCategory);
+
+ if (baseCategory == XsdSimpleType::SimpleTypeList) {
+ const XsdSimpleType::Ptr baseSimpleType = complexBaseType->contentType()->simpleType();
+ anonType->setItemType(baseSimpleType->itemType());
+ }
+
+ anonType->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+ anonType->setWxsSuperType(complexBaseType->contentType()->simpleType());
+ anonType->setFacets(complexTypeFacets(complexType));
+
+ QSet<AnySimpleType::Ptr> visitedPrimitiveTypes;
+ const AnySimpleType::Ptr primitiveType = findPrimitiveType(anonType->wxsSuperType(), visitedPrimitiveTypes);
+ anonType->setPrimitiveType(primitiveType);
+
+ complexType->contentType()->setSimpleType(anonType);
+
+ m_schema->addAnonymousType(anonType);
+ m_componentLocationHash.insert(anonType, m_componentLocationHash.value(complexType));
+ }
+ } else if (complexBaseType->derivationMethod() == XsdComplexType::DerivationExtension) { // 3
+ complexType->contentType()->setSimpleType(complexBaseType->contentType()->simpleType());
+ }
+ } else if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed &&
+ complexType->derivationMethod() == XsdComplexType::DerivationRestriction &&
+ XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle())) { // 2
+ // simple type was already set in parser
+
+ const XsdSimpleType::Ptr anonType(new XsdSimpleType());
+ anonType->setCategory(complexType->contentType()->simpleType()->category());
+ anonType->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+ anonType->setWxsSuperType(complexType->contentType()->simpleType());
+ anonType->setFacets(complexTypeFacets(complexType));
+
+ QSet<AnySimpleType::Ptr> visitedPrimitiveTypes;
+ const AnySimpleType::Ptr primitiveType = findPrimitiveType(anonType->wxsSuperType(), visitedPrimitiveTypes);
+ anonType->setPrimitiveType(primitiveType);
+
+ complexType->contentType()->setSimpleType(anonType);
+
+ m_schema->addAnonymousType(anonType);
+ m_componentLocationHash.insert(anonType, m_componentLocationHash.value(complexType));
+ } else {
+ complexType->contentType()->setSimpleType(BuiltinTypes::xsAnySimpleType);
+ }
+ } else if (baseType->isSimpleType()) { // 4
+ complexType->contentType()->setSimpleType(baseType);
+ } else { // 5
+ complexType->contentType()->setSimpleType(BuiltinTypes::xsAnySimpleType);
+ }
+}
+
+void XsdSchemaResolver::resolveComplexContentComplexTypes()
+{
+ XsdComplexType::List complexTypes;
+
+ // first collect the global complex types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema())
+ complexTypes.append(types.at(i));
+ }
+
+ // then collect all anonymous simple types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (anonymousTypes.at(i)->isComplexType() && anonymousTypes.at(i)->isDefinedBySchema())
+ complexTypes.append(anonymousTypes.at(i));
+ }
+
+ QSet<XsdComplexType::Ptr> visitedTypes;
+ for (int i = 0; i < complexTypes.count(); ++i) {
+ if (XsdComplexType::Ptr(complexTypes.at(i))->contentType()->variety() != XsdComplexType::ContentType::Simple)
+ resolveComplexContentComplexTypes(complexTypes.at(i), visitedTypes);
+ }
+}
+
+void XsdSchemaResolver::resolveComplexContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes)
+{
+ if (visitedTypes.contains(complexType))
+ return;
+ else
+ visitedTypes.insert(complexType);
+
+ ComplexContentType item;
+ bool foundCorrespondingItem = false;
+ for (int i = 0; i < m_complexContentTypes.count(); ++i) {
+ if (m_complexContentTypes.at(i).complexType == complexType) {
+ item = m_complexContentTypes.at(i);
+ foundCorrespondingItem = true;
+ break;
+ }
+ }
+
+ if (!foundCorrespondingItem)
+ return;
+
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+
+ // at this point simple types have been resolved already, so we care about
+ // complex types here only
+ if (baseType->isComplexType() && baseType->isDefinedBySchema())
+ resolveComplexContentComplexTypes(XsdComplexType::Ptr(baseType), visitedTypes);
+
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctcc.common
+
+ // 3
+ XsdParticle::Ptr effectiveContent;
+ if (!item.explicitContent) { // 3.1
+ if (item.effectiveMixed == true) { // 3.1.1
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setMinimumOccurs(1);
+ particle->setMaximumOccurs(1);
+ particle->setMaximumOccursUnbounded(false);
+
+ const XsdModelGroup::Ptr sequence(new XsdModelGroup());
+ sequence->setCompositor(XsdModelGroup::SequenceCompositor);
+ particle->setTerm(sequence);
+
+ effectiveContent = particle;
+ } else { // 3.1.2
+ effectiveContent = XsdParticle::Ptr();
+ }
+ } else { // 3.2
+ effectiveContent = item.explicitContent;
+ }
+
+ // 4
+ XsdComplexType::ContentType::Ptr explicitContentType(new XsdComplexType::ContentType());
+ if (item.complexType->derivationMethod() == XsdComplexType::DerivationRestriction) { // 4.1
+ if (!effectiveContent) { // 4.1.1
+ explicitContentType->setVariety(XsdComplexType::ContentType::Empty);
+ } else { // 4.1.2
+ if (item.effectiveMixed == true)
+ explicitContentType->setVariety(XsdComplexType::ContentType::Mixed);
+ else
+ explicitContentType->setVariety(XsdComplexType::ContentType::ElementOnly);
+
+ explicitContentType->setParticle(effectiveContent);
+ }
+ } else if (item.complexType->derivationMethod() == XsdComplexType::DerivationExtension) { // 4.2
+ const SchemaType::Ptr baseType = item.complexType->wxsSuperType();
+ if (baseType->isSimpleType() || (baseType->isComplexType() && baseType->isDefinedBySchema() && (XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::Empty ||
+ XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::Simple))) { // 4.2.1
+ if (!effectiveContent) {
+ explicitContentType->setVariety(XsdComplexType::ContentType::Empty);
+ } else {
+ if (item.effectiveMixed == true)
+ explicitContentType->setVariety(XsdComplexType::ContentType::Mixed);
+ else
+ explicitContentType->setVariety(XsdComplexType::ContentType::ElementOnly);
+
+ explicitContentType->setParticle(effectiveContent);
+ }
+ } else if (baseType->isComplexType() && baseType->isDefinedBySchema() && (XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::ElementOnly ||
+ XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::Mixed) && !effectiveContent) { // 4.2.2
+ const XsdComplexType::Ptr complexBaseType(baseType);
+
+ explicitContentType = complexBaseType->contentType();
+ } else { // 4.2.3
+ explicitContentType->setVariety(item.effectiveMixed ? XsdComplexType::ContentType::Mixed : XsdComplexType::ContentType::ElementOnly);
+
+ XsdParticle::Ptr baseParticle;
+ if (baseType == BuiltinTypes::xsAnyType) {
+ // we need a workaround here, since the xsAnyType is no real (aka XsdComplexType) complex type...
+
+ baseParticle = XsdParticle::Ptr(new XsdParticle());
+ baseParticle->setMinimumOccurs(1);
+ baseParticle->setMaximumOccurs(1);
+ baseParticle->setMaximumOccursUnbounded(false);
+
+ const XsdModelGroup::Ptr group(new XsdModelGroup());
+ group->setCompositor(XsdModelGroup::SequenceCompositor);
+
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setMinimumOccurs(0);
+ particle->setMaximumOccursUnbounded(true);
+
+ const XsdWildcard::Ptr wildcard(new XsdWildcard());
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ wildcard->setProcessContents(XsdWildcard::Lax);
+
+ particle->setTerm(wildcard);
+ XsdParticle::List particles;
+ particles.append(particle);
+ group->setParticles(particles);
+ baseParticle->setTerm(group);
+ } else {
+ const XsdComplexType::Ptr complexBaseType(baseType);
+ baseParticle = complexBaseType->contentType()->particle();
+ }
+ if (baseParticle && baseParticle->term()->isModelGroup() && (XsdModelGroup::Ptr(baseParticle->term())->compositor() == XsdModelGroup::AllCompositor) &&
+ (!item.explicitContent)) { // 4.2.3.1
+
+ explicitContentType->setParticle(baseParticle);
+ } else if (baseParticle && baseParticle->term()->isModelGroup() && (XsdModelGroup::Ptr(baseParticle->term())->compositor() == XsdModelGroup::AllCompositor) &&
+ (effectiveContent->term()->isModelGroup() && (XsdModelGroup::Ptr(effectiveContent->term())->compositor() == XsdModelGroup::AllCompositor))) { // 4.2.3.2
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setMinimumOccurs(effectiveContent->minimumOccurs());
+ particle->setMaximumOccurs(1);
+ particle->setMaximumOccursUnbounded(false);
+
+ const XsdModelGroup::Ptr group(new XsdModelGroup());
+ group->setCompositor(XsdModelGroup::AllCompositor);
+ XsdParticle::List particles = XsdModelGroup::Ptr(baseParticle->term())->particles();
+ particles << XsdModelGroup::Ptr(effectiveContent->term())->particles();
+ group->setParticles(particles);
+ particle->setTerm(group);
+
+ explicitContentType->setParticle(particle);
+ } else { // 4.2.3.3
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setMinimumOccurs(1);
+ particle->setMaximumOccurs(1);
+ particle->setMaximumOccursUnbounded(false);
+
+ const XsdModelGroup::Ptr group(new XsdModelGroup());
+ group->setCompositor(XsdModelGroup::SequenceCompositor);
+
+ if (effectiveContent && effectiveContent->term()->isModelGroup() && XsdModelGroup::Ptr(effectiveContent->term())->compositor() == XsdModelGroup::AllCompositor) {
+ m_context->error(QtXmlPatterns::tr("Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type.")
+ .arg(formatType(m_namePool, complexType)).arg(formatKeyword("all")), XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+
+ if (baseParticle && baseParticle->term()->isModelGroup() && XsdModelGroup::Ptr(baseParticle->term())->compositor() == XsdModelGroup::AllCompositor) {
+ m_context->error(QtXmlPatterns::tr("Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, baseType))
+ .arg(formatKeyword("all")), XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+
+ XsdParticle::List particles;
+ if (baseParticle)
+ particles << baseParticle;
+ if (effectiveContent)
+ particles << effectiveContent;
+ group->setParticles(particles);
+ particle->setTerm(group);
+
+ explicitContentType->setParticle(particle);
+ }
+
+ if (baseType->isDefinedBySchema()) { // xs:anyType has no open content
+ const XsdComplexType::Ptr complexBaseType(baseType);
+ explicitContentType->setOpenContent(complexBaseType->contentType()->openContent());
+ }
+ }
+ }
+
+ // 5
+ XsdComplexType::OpenContent::Ptr wildcardElement;
+ if (item.complexType->contentType()->openContent()) { // 5.1
+ wildcardElement = item.complexType->contentType()->openContent();
+ } else {
+ if (m_defaultOpenContent) { // 5.2
+ if ((explicitContentType->variety() != XsdComplexType::ContentType::Empty) || // 5.2.1
+ (explicitContentType->variety() == XsdComplexType::ContentType::Empty && m_defaultOpenContentAppliesToEmpty)) { // 5.2.2
+ wildcardElement = m_defaultOpenContent;
+ }
+ }
+ }
+
+ // 6
+ if (!wildcardElement) { // 6.1
+ item.complexType->setContentType(explicitContentType);
+ } else {
+ if (wildcardElement->mode() == XsdComplexType::OpenContent::None) { // 6.2
+ const XsdComplexType::ContentType::Ptr contentType(new XsdComplexType::ContentType());
+ contentType->setVariety(explicitContentType->variety());
+ contentType->setParticle(explicitContentType->particle());
+
+ item.complexType->setContentType(contentType);
+ } else { // 6.3
+ const XsdComplexType::ContentType::Ptr contentType(new XsdComplexType::ContentType());
+
+ if (explicitContentType->variety() == XsdComplexType::ContentType::Empty)
+ contentType->setVariety(XsdComplexType::ContentType::ElementOnly);
+ else
+ contentType->setVariety(explicitContentType->variety());
+
+ if (explicitContentType->variety() == XsdComplexType::ContentType::Empty) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setMinimumOccurs(1);
+ particle->setMaximumOccurs(1);
+ const XsdModelGroup::Ptr sequence(new XsdModelGroup());
+ sequence->setCompositor(XsdModelGroup::SequenceCompositor);
+ particle->setTerm(sequence);
+ contentType->setParticle(particle);
+ } else {
+ contentType->setParticle(explicitContentType->particle());
+ }
+
+ const XsdComplexType::OpenContent::Ptr openContent(new XsdComplexType::OpenContent());
+ if (wildcardElement)
+ openContent->setMode(wildcardElement->mode());
+ else
+ openContent->setMode(XsdComplexType::OpenContent::Interleave);
+
+ if (wildcardElement)
+ openContent->setWildcard(wildcardElement->wildcard());
+
+ item.complexType->setContentType(contentType);
+ }
+ }
+}
+
+void XsdSchemaResolver::resolveAttributeTypes()
+{
+ for (int i = 0; i < m_attributeTypes.count(); ++i) {
+ const AttributeType item = m_attributeTypes.at(i);
+
+ SchemaType::Ptr type = m_schema->type(item.typeName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.typeName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, item.typeName))
+ .arg(formatElement("attribute")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ if (!type->isSimpleType() && type->category() != SchemaType::None) {
+ m_context->error(QtXmlPatterns::tr("Type of %1 element must be a simple type, %2 is not.")
+ .arg(formatElement("attribute"))
+ .arg(formatType(m_namePool, item.typeName)),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+
+ item.attribute->setType(type);
+ }
+}
+
+void XsdSchemaResolver::resolveAlternativeTypes()
+{
+ for (int i = 0; i < m_alternativeTypes.count(); ++i) {
+ const AlternativeType item = m_alternativeTypes.at(i);
+
+ SchemaType::Ptr type = m_schema->type(item.typeName);
+ if (!type) {
+ // maybe it's a basic type...
+ type = m_context->schemaTypeFactory()->createSchemaType(item.typeName);
+ if (!type) {
+ m_context->error(QtXmlPatterns::tr("Type %1 of %2 element cannot be resolved.")
+ .arg(formatType(m_namePool, item.typeName))
+ .arg(formatElement("alternative")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+ }
+
+ item.alternative->setType(type);
+ }
+
+ for (int i = 0; i < m_alternativeTypeElements.count(); ++i) {
+ const AlternativeTypeElement item = m_alternativeTypeElements.at(i);
+ item.alternative->setType(item.element->type());
+ }
+}
+
+bool hasCircularSubstitutionGroup(const XsdElement::Ptr &current, const XsdElement::Ptr &head, const NamePool::Ptr &namePool)
+{
+ if (current == head)
+ return true;
+ else {
+ const XsdElement::List elements = current->substitutionGroupAffiliations();
+ for (int i = 0; i < elements.count(); ++i) {
+ if (hasCircularSubstitutionGroup(elements.at(i), head, namePool))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void XsdSchemaResolver::resolveSubstitutionGroupAffiliations()
+{
+ for (int i = 0; i < m_substitutionGroupAffiliations.count(); ++i) {
+ const SubstitutionGroupAffiliation item = m_substitutionGroupAffiliations.at(i);
+
+ XsdElement::List affiliations;
+ for (int j = 0; j < item.elementNames.count(); ++j) {
+ const XsdElement::Ptr element = m_schema->element(item.elementNames.at(j));
+ if (!element) {
+ m_context->error(QtXmlPatterns::tr("Substitution group %1 of %2 element cannot be resolved.")
+ .arg(formatKeyword(m_namePool, item.elementNames.at(j)))
+ .arg(formatElement("element")),
+ XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#e-props-correct 5)
+ if (hasCircularSubstitutionGroup(element, item.element, m_namePool)) {
+ m_context->error(QtXmlPatterns::tr("Substitution group %1 has circular definition.").arg(formatKeyword(m_namePool, item.elementNames.at(j))), XsdSchemaContext::XSDError, item.location);
+ return;
+ }
+
+ affiliations.append(element);
+ }
+
+ item.element->setSubstitutionGroupAffiliations(affiliations);
+ }
+
+ for (int i = 0; i < m_substitutionGroupTypes.count(); ++i) {
+ const XsdElement::Ptr element = m_substitutionGroupTypes.at(i);
+ element->setType(element->substitutionGroupAffiliations().first()->type());
+ }
+}
+
+bool isSubstGroupHeadOf(const XsdElement::Ptr &head, const XsdElement::Ptr &element, const NamePool::Ptr &namePool)
+{
+ if (head->name(namePool) == element->name(namePool))
+ return true;
+
+ const XsdElement::List affiliations = element->substitutionGroupAffiliations();
+ for (int i = 0; i < affiliations.count(); ++i) {
+ if (isSubstGroupHeadOf(head, affiliations.at(i), namePool))
+ return true;
+ }
+
+ return false;
+}
+
+void XsdSchemaResolver::resolveSubstitutionGroups()
+{
+ const XsdElement::List elements = m_schema->elements();
+ for (int i = 0; i < elements.count(); ++i) {
+ const XsdElement::Ptr element = elements.at(i);
+
+ // the element is always itself in the substitution group
+ element->addSubstitutionGroup(element);
+
+ for (int j = 0; j < elements.count(); ++j) {
+ if (i == j)
+ continue;
+
+ if (isSubstGroupHeadOf(element, elements.at(j), m_namePool))
+ element->addSubstitutionGroup(elements.at(j));
+ }
+ }
+}
+
+void XsdSchemaResolver::resolveTermReferences()
+{
+ // first the global complex types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = types.at(i);
+ if (complexType->contentType()->variety() != XsdComplexType::ContentType::ElementOnly && complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed)
+ continue;
+
+ resolveTermReference(complexType->contentType()->particle(), QSet<QXmlName>());
+ }
+
+ // then all anonymous complex types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (!(anonymousTypes.at(i)->isComplexType()) || !anonymousTypes.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = anonymousTypes.at(i);
+ if (complexType->contentType()->variety() != XsdComplexType::ContentType::ElementOnly && complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed)
+ continue;
+
+ resolveTermReference(complexType->contentType()->particle(), QSet<QXmlName>());
+ }
+
+ const XsdModelGroup::List groups = m_schema->elementGroups();
+ for (int i = 0; i < groups.count(); ++i) {
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setTerm(groups.at(i));
+ resolveTermReference(particle, QSet<QXmlName>());
+ }
+}
+
+void XsdSchemaResolver::resolveTermReference(const XsdParticle::Ptr &particle, QSet<QXmlName> visitedGroups)
+{
+ if (!particle)
+ return;
+
+ const XsdTerm::Ptr term = particle->term();
+
+ // if it is a model group, we iterate over it recursive...
+ if (term->isModelGroup()) {
+ const XsdModelGroup::Ptr modelGroup = term;
+ const XsdParticle::List particles = modelGroup->particles();
+
+ for (int i = 0; i < particles.count(); ++i) {
+ resolveTermReference(particles.at(i), visitedGroups);
+ }
+
+ // check for unique names of elements inside all compositor
+ if (modelGroup->compositor() != XsdModelGroup::ChoiceCompositor) {
+ for (int i = 0; i < particles.count(); ++i) {
+ const XsdParticle::Ptr particle = particles.at(i);
+ const XsdTerm::Ptr term = particle->term();
+
+ if (!(term->isElement()))
+ continue;
+
+ for (int j = 0; j < particles.count(); ++j) {
+ const XsdParticle::Ptr otherParticle = particles.at(j);
+ const XsdTerm::Ptr otherTerm = otherParticle->term();
+
+ if (otherTerm->isElement() && i != j) {
+ const XsdElement::Ptr element = term;
+ const XsdElement::Ptr otherElement = otherTerm;
+
+ if (element->name(m_namePool) == otherElement->name(m_namePool)) {
+ if (modelGroup->compositor() == XsdModelGroup::AllCompositor) {
+ m_context->error(QtXmlPatterns::tr("Duplicated element names %1 in %2 element.")
+ .arg(formatKeyword(element->displayName(m_namePool)))
+ .arg(formatElement("all")),
+ XsdSchemaContext::XSDError, sourceLocation(modelGroup));
+ return;
+ } else if (modelGroup->compositor() == XsdModelGroup::SequenceCompositor) {
+ if (element->type() != otherElement->type()) { // not same variety
+ m_context->error(QtXmlPatterns::tr("Duplicated element names %1 in %2 element.")
+ .arg(formatKeyword(element->displayName(m_namePool)))
+ .arg(formatElement("sequence")),
+ XsdSchemaContext::XSDError, sourceLocation(modelGroup));
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+ // ...otherwise we have reached the end of recursion...
+ if (!term->isReference())
+ return;
+
+ // ...or we have reached a reference term that must be resolved
+ const XsdReference::Ptr reference = term;
+ switch (reference->type()) {
+ case XsdReference::Element:
+ {
+ const XsdElement::Ptr element = m_schema->element(reference->referenceName());
+ if (element) {
+ particle->setTerm(element);
+ } else {
+ m_context->error(QtXmlPatterns::tr("Reference %1 of %2 element cannot be resolved.")
+ .arg(formatKeyword(m_namePool, reference->referenceName()))
+ .arg(formatElement("element")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return;
+ }
+ }
+ break;
+ case XsdReference::ModelGroup:
+ {
+ const XsdModelGroup::Ptr modelGroup = m_schema->elementGroup(reference->referenceName());
+ if (modelGroup) {
+ if (visitedGroups.contains(modelGroup->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Circular group reference for %1.").arg(formatKeyword(modelGroup->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ } else {
+ visitedGroups.insert(modelGroup->name(m_namePool));
+ }
+
+ particle->setTerm(modelGroup);
+
+ // start recursive iteration here as well to get all references resolved
+ const XsdParticle::List particles = modelGroup->particles();
+ for (int i = 0; i < particles.count(); ++i) {
+ resolveTermReference(particles.at(i), visitedGroups);
+ }
+
+ if (modelGroup->compositor() == XsdModelGroup::AllCompositor) {
+ if (m_allGroups.contains(reference)) {
+ m_context->error(QtXmlPatterns::tr("%1 element is not allowed in this scope").arg(formatElement("all.")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return;
+ }
+ if (particle->maximumOccursUnbounded() || particle->maximumOccurs() != 1) {
+ m_context->error(QtXmlPatterns::tr("%1 element cannot have %2 attribute with value other than %3.")
+ .arg(formatElement("all"))
+ .arg(formatAttribute("maxOccurs"))
+ .arg(formatData("1")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return;
+ }
+ if (particle->minimumOccurs() != 0 && particle->minimumOccurs() != 1) {
+ m_context->error(QtXmlPatterns::tr("%1 element cannot have %2 attribute with value other than %3 or %4.")
+ .arg(formatElement("all"))
+ .arg(formatAttribute("minOccurs"))
+ .arg(formatData("0"))
+ .arg(formatData("1")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return;
+ }
+ }
+ } else {
+ m_context->error(QtXmlPatterns::tr("Reference %1 of %2 element cannot be resolved.")
+ .arg(formatKeyword(m_namePool, reference->referenceName()))
+ .arg(formatElement("group")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return;
+ }
+ }
+ break;
+ }
+}
+
+void XsdSchemaResolver::resolveAttributeTermReferences()
+{
+ // first all global attribute groups
+ const XsdAttributeGroup::List attributeGroups = m_schema->attributeGroups();
+ for (int i = 0; i < attributeGroups.count(); ++i) {
+ XsdWildcard::Ptr wildcard = attributeGroups.at(i)->wildcard();
+ const XsdAttributeUse::List uses = resolveAttributeTermReferences(attributeGroups.at(i)->attributeUses(), wildcard, QSet<QXmlName>());
+ attributeGroups.at(i)->setAttributeUses(uses);
+ attributeGroups.at(i)->setWildcard(wildcard);
+ }
+
+ // then the global complex types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = types.at(i);
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+
+ XsdWildcard::Ptr wildcard = complexType->attributeWildcard();
+ const XsdAttributeUse::List uses = resolveAttributeTermReferences(attributeUses, wildcard, QSet<QXmlName>());
+ complexType->setAttributeUses(uses);
+ complexType->setAttributeWildcard(wildcard);
+ }
+
+ // and afterwards all anonymous complex types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (!(anonymousTypes.at(i)->isComplexType()) || !anonymousTypes.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = anonymousTypes.at(i);
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+
+ XsdWildcard::Ptr wildcard = complexType->attributeWildcard();
+ const XsdAttributeUse::List uses = resolveAttributeTermReferences(attributeUses, wildcard, QSet<QXmlName>());
+ complexType->setAttributeUses(uses);
+ complexType->setAttributeWildcard(wildcard);
+ }
+}
+
+XsdAttributeUse::List XsdSchemaResolver::resolveAttributeTermReferences(const XsdAttributeUse::List &attributeUses, XsdWildcard::Ptr &wildcard, QSet<QXmlName> visitedAttributeGroups)
+{
+ XsdAttributeUse::List resolvedAttributeUses;
+
+ for (int i = 0; i < attributeUses.count(); ++i) {
+ const XsdAttributeUse::Ptr attributeUse = attributeUses.at(i);
+ if (attributeUse->isAttributeUse()) {
+ // it is a real attribute use, so no need to resolve it
+ resolvedAttributeUses.append(attributeUse);
+ } else if (attributeUse->isReference()) {
+ // it is just a reference, so resolve it to the real attribute use
+
+ const XsdAttributeReference::Ptr reference = attributeUse;
+ if (reference->type() == XsdAttributeReference::AttributeUse) {
+
+ // lookup the real attribute
+ const XsdAttribute::Ptr attribute = m_schema->attribute(reference->referenceName());
+ if (!attribute) {
+ m_context->error(QtXmlPatterns::tr("Reference %1 of %2 element cannot be resolved.")
+ .arg(formatKeyword(m_namePool, reference->referenceName()))
+ .arg(formatElement("attribute")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return XsdAttributeUse::List();
+ }
+
+ // if both, reference and definition have a fixed or default value set, then they must be equal
+ if (attribute->valueConstraint() && attributeUse->valueConstraint()) {
+ if (attribute->valueConstraint()->value() != attributeUse->valueConstraint()->value()) {
+ m_context->error(QtXmlPatterns::tr("%1 or %2 attribute of reference %3 does not match with the attribute declaration %4.")
+ .arg(formatAttribute("fixed"))
+ .arg(formatAttribute("default"))
+ .arg(formatKeyword(m_namePool, reference->referenceName()))
+ .arg(formatKeyword(attribute->displayName(m_namePool))),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return XsdAttributeUse::List();
+ }
+ }
+
+ attributeUse->setAttribute(attribute);
+ if (!attributeUse->valueConstraint() && attribute->valueConstraint())
+ attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(attribute->valueConstraint()));
+
+ resolvedAttributeUses.append(attributeUse);
+ } else if (reference->type() == XsdAttributeReference::AttributeGroup) {
+ const XsdAttributeGroup::Ptr attributeGroup = m_schema->attributeGroup(reference->referenceName());
+ if (!attributeGroup) {
+ m_context->error(QtXmlPatterns::tr("Reference %1 of %2 element cannot be resolved.")
+ .arg(formatKeyword(m_namePool, reference->referenceName()))
+ .arg(formatElement("attributeGroup")),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return XsdAttributeUse::List();
+ }
+ if (visitedAttributeGroups.contains(attributeGroup->name(m_namePool))) {
+ m_context->error(QtXmlPatterns::tr("Attribute group %1 has circular reference.").arg(formatKeyword(m_namePool, reference->referenceName())),
+ XsdSchemaContext::XSDError, reference->sourceLocation());
+ return XsdAttributeUse::List();
+ } else {
+ visitedAttributeGroups.insert(attributeGroup->name(m_namePool));
+ }
+
+ // resolve attribute wildcards as defined in http://www.w3.org/TR/xmlschema11-1/#declare-attributeGroup-wildcard
+ XsdWildcard::Ptr childWildcard;
+ resolvedAttributeUses << resolveAttributeTermReferences(attributeGroup->attributeUses(), childWildcard, visitedAttributeGroups);
+ if (!childWildcard) {
+ if (attributeGroup->wildcard()) {
+ if (wildcard) {
+ const XsdWildcard::ProcessContents contents = wildcard->processContents();
+ wildcard = XsdSchemaHelper::wildcardIntersection(wildcard, attributeGroup->wildcard());
+ wildcard->setProcessContents(contents);
+ } else {
+ wildcard = attributeGroup->wildcard();
+ }
+ }
+ } else {
+ XsdWildcard::Ptr newWildcard;
+ if (attributeGroup->wildcard()) {
+ const XsdWildcard::ProcessContents contents = attributeGroup->wildcard()->processContents();
+ newWildcard = XsdSchemaHelper::wildcardIntersection(attributeGroup->wildcard(), childWildcard);
+ newWildcard->setProcessContents(contents);
+ } else {
+ newWildcard = childWildcard;
+ }
+
+ if (wildcard) {
+ const XsdWildcard::ProcessContents contents = wildcard->processContents();
+ wildcard = XsdSchemaHelper::wildcardIntersection(wildcard, newWildcard);
+ wildcard->setProcessContents(contents);
+ } else {
+ wildcard = newWildcard;
+ }
+ }
+ }
+ }
+ }
+
+ return resolvedAttributeUses;
+}
+
+void XsdSchemaResolver::resolveAttributeInheritance()
+{
+ // collect the global and anonymous complex types
+ SchemaType::List types = m_schema->types();
+ types << m_schema->anonymousTypes();
+
+ QSet<XsdComplexType::Ptr> visitedTypes;
+ for (int i = 0; i < types.count(); ++i) {
+ if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema())
+ continue;
+
+ const XsdComplexType::Ptr complexType = types.at(i);
+
+ resolveAttributeInheritance(complexType, visitedTypes);
+ }
+}
+
+bool isValidWildcardRestriction(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &baseWildcard)
+{
+ if (wildcard->namespaceConstraint()->variety() == baseWildcard->namespaceConstraint()->variety()) {
+ if (!XsdSchemaHelper::checkWildcardProcessContents(baseWildcard, wildcard))
+ return false;
+ }
+
+ if (wildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Any &&
+ baseWildcard->namespaceConstraint()->variety() != XsdWildcard::NamespaceConstraint::Any ) {
+ return false;
+ }
+ if (baseWildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Not &&
+ wildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Enumeration) {
+ if (!baseWildcard->namespaceConstraint()->namespaces().intersect(wildcard->namespaceConstraint()->namespaces()).isEmpty())
+ return false;
+ }
+ if (baseWildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Enumeration &&
+ wildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Enumeration) {
+ if (!wildcard->namespaceConstraint()->namespaces().subtract(baseWildcard->namespaceConstraint()->namespaces()).isEmpty())
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Since we inherit the attributes from our base class we have to walk up in the
+ * inheritance hierarchy first and resolve the attribute inheritance top-down.
+ */
+void XsdSchemaResolver::resolveAttributeInheritance(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes)
+{
+ if (visitedTypes.contains(complexType))
+ return;
+ else
+ visitedTypes.insert(complexType);
+
+ const SchemaType::Ptr baseType = complexType->wxsSuperType();
+ Q_ASSERT(baseType);
+
+ if (!(baseType->isComplexType()) || !baseType->isDefinedBySchema())
+ return;
+
+ const XsdComplexType::Ptr complexBaseType = baseType;
+
+ resolveAttributeInheritance(complexBaseType, visitedTypes);
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.attuses
+
+ // 1 and 2 (the attribute groups have been resolved here already)
+ const XsdAttributeUse::List uses = complexBaseType->attributeUses();
+
+ if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) { // 3.2
+ const XsdAttributeUse::List currentUses = complexType->attributeUses();
+
+ // 3.2.1 and 3.2.2 As we also keep the prohibited attributes as objects, the algorithm below
+ // handles both the same way
+
+ // add only these attribute uses of the base type that match one of the following criteria:
+ // 1: there is no attribute use with the same name in type
+ // 2: there is no attribute with the same name marked as prohibited in type
+ for (int j = 0; j < uses.count(); ++j) {
+ const XsdAttributeUse::Ptr use = uses.at(j);
+ bool found = false;
+ for (int k = 0; k < currentUses.count(); ++k) {
+ if (use->attribute()->name(m_namePool) == currentUses.at(k)->attribute()->name(m_namePool)) {
+ found = true;
+
+ // check if prohibited usage is violated
+ if ((use->useType() == XsdAttributeUse::ProhibitedUse) && (currentUses.at(k)->useType() != XsdAttributeUse::ProhibitedUse)) {
+ m_context->error(QtXmlPatterns::tr("%1 attribute in %2 must have %3 use like in base type %4.")
+ .arg(formatAttribute(use->attribute()->displayName(m_namePool)))
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatData("prohibited"))
+ .arg(formatType(m_namePool, complexBaseType)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+
+ break;
+ }
+ }
+
+ if (!found && uses.at(j)->useType() != XsdAttributeUse::ProhibitedUse) {
+ complexType->addAttributeUse(uses.at(j));
+ }
+ }
+ } else if (complexType->derivationMethod() == XsdComplexType::DerivationExtension) { // 3.1
+ QHash<QXmlName, XsdAttributeUse::Ptr> availableUses;
+
+ // fill hash with attribute uses of current type for faster lookup
+ {
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+
+ for (int i = 0; i < attributeUses.count(); ++i) {
+ availableUses.insert(attributeUses.at(i)->attribute()->name(m_namePool), attributeUses.at(i));
+ }
+ }
+
+ // just add the attribute uses of the base type
+ for (int i = 0; i < uses.count(); ++i) {
+ const XsdAttributeUse::Ptr currentAttributeUse = uses.at(i);
+
+ // if the base type defines the attribute as prohibited but we override it in current type, then don't copy the prohibited attribute use
+ if ((currentAttributeUse->useType() == XsdAttributeUse::ProhibitedUse) && availableUses.contains(currentAttributeUse->attribute()->name(m_namePool)))
+ continue;
+
+ complexType->addAttributeUse(uses.at(i));
+ }
+ }
+
+ // handle attribute wildcards: @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.anyatt
+
+ // 1
+ const XsdWildcard::Ptr completeWildcard(complexType->attributeWildcard());
+
+ if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) {
+ if (complexType->wxsSuperType()->isComplexType() && complexType->wxsSuperType()->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexBaseType(complexType->wxsSuperType());
+ if (complexType->attributeWildcard()) {
+ if (complexBaseType->attributeWildcard()) {
+ if (!isValidWildcardRestriction(complexType->attributeWildcard(), complexBaseType->attributeWildcard())) {
+ m_context->error(QtXmlPatterns::tr("Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, complexBaseType)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ } else {
+ m_context->error(QtXmlPatterns::tr("%1 has attribute wildcard but its base type %2 has not.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, complexBaseType)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+ }
+ complexType->setAttributeWildcard(completeWildcard); // 2.1
+ } else if (complexType->derivationMethod() == XsdComplexType::DerivationExtension) {
+ XsdWildcard::Ptr baseWildcard; // 2.2.1
+ if (complexType->wxsSuperType()->isComplexType() && complexType->wxsSuperType()->isDefinedBySchema())
+ baseWildcard = XsdComplexType::Ptr(complexType->wxsSuperType())->attributeWildcard(); // 2.2.1.1
+ else
+ baseWildcard = XsdWildcard::Ptr(); // 2.2.1.2
+
+ if (!baseWildcard) {
+ complexType->setAttributeWildcard(completeWildcard); // 2.2.2.1
+ } else if (!completeWildcard) {
+ complexType->setAttributeWildcard(baseWildcard); // 2.2.2.2
+ } else {
+ XsdWildcard::Ptr unionWildcard = XsdSchemaHelper::wildcardUnion(completeWildcard, baseWildcard);
+ if (unionWildcard) {
+ unionWildcard->setProcessContents(completeWildcard->processContents());
+ complexType->setAttributeWildcard(unionWildcard); // 2.2.2.3
+ } else {
+ m_context->error(QtXmlPatterns::tr("Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible.")
+ .arg(formatType(m_namePool, complexType))
+ .arg(formatType(m_namePool, complexBaseType)),
+ XsdSchemaContext::XSDError, sourceLocation(complexType));
+ return;
+ }
+ }
+ }
+}
+
+void XsdSchemaResolver::resolveEnumerationFacetValues()
+{
+ XsdSimpleType::List simpleTypes;
+
+ // first collect the global simple types
+ const SchemaType::List types = m_schema->types();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i)->isSimpleType())
+ simpleTypes.append(types.at(i));
+ }
+
+ // then collect all anonymous simple types
+ const SchemaType::List anonymousTypes = m_schema->anonymousTypes();
+ for (int i = 0; i < anonymousTypes.count(); ++i) {
+ if (anonymousTypes.at(i)->isSimpleType())
+ simpleTypes.append(anonymousTypes.at(i));
+ }
+ // process all simple types
+ for (int i = 0; i < simpleTypes.count(); ++i) {
+ const XsdSimpleType::Ptr simpleType = simpleTypes.at(i);
+
+ // we resolve the enumeration values only for xs:QName and xs:NOTATION based types
+ if (BuiltinTypes::xsQName->wxsTypeMatches(simpleType) ||
+ BuiltinTypes::xsNOTATION->wxsTypeMatches(simpleType)) {
+ const XsdFacet::Hash facets = simpleType->facets();
+ if (facets.contains(XsdFacet::Enumeration)) {
+ AtomicValue::List newValues;
+
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const AtomicValue::List values = facet->multiValue();
+ for (int j = 0; j < values.count(); ++j) {
+ const AtomicValue::Ptr value = values.at(j);
+
+ Q_ASSERT(m_enumerationFacetValues.contains(value));
+ const NamespaceSupport support( m_enumerationFacetValues.value(value) );
+
+ const QString qualifiedName = value->as<DerivedString<TypeString> >()->stringValue();
+ if (!XPathHelper::isQName(qualifiedName)) {
+ m_context->error(QtXmlPatterns::tr("Enumeration facet contains invalid content: {%1} is not a value of type %2.")
+ .arg(formatData(qualifiedName))
+ .arg(formatType(m_namePool, BuiltinTypes::xsQName)),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+
+ QXmlName qNameValue;
+ bool result = support.processName(qualifiedName, NamespaceSupport::ElementName, qNameValue);
+ if (!result) {
+ m_context->error(QtXmlPatterns::tr("Namespace prefix of qualified name %1 is not defined.").arg(formatData(qualifiedName)),
+ XsdSchemaContext::XSDError, sourceLocation(simpleType));
+ return;
+ }
+
+ newValues.append(QNameValue::fromValue(m_namePool, qNameValue));
+ }
+ facet->setMultiValue(newValues);
+ }
+ }
+ }
+}
+
+QSourceLocation XsdSchemaResolver::sourceLocation(const NamedSchemaComponent::Ptr component) const
+{
+ if (m_componentLocationHash.contains(component)) {
+ return m_componentLocationHash.value(component);
+ } else {
+ QSourceLocation location;
+ location.setLine(1);
+ location.setColumn(1);
+ location.setUri(QString::fromLatin1("dummyUri"));
+
+ return location;
+ }
+}
+
+XsdFacet::Hash XsdSchemaResolver::complexTypeFacets(const XsdComplexType::Ptr &complexType) const
+{
+ for (int i = 0; i < m_complexBaseTypes.count(); ++i) {
+ if (m_complexBaseTypes.at(i).complexType == complexType)
+ return m_complexBaseTypes.at(i).facets;
+ }
+
+ return XsdFacet::Hash();
+}
+
+void XsdSchemaResolver::checkRedefinedGroups()
+{
+ for (int i = 0; i < m_redefinedGroups.count(); ++i) {
+ const RedefinedGroups item = m_redefinedGroups.at(i);
+
+ // create dummy particles...
+ const XsdParticle::Ptr redefinedParticle(new XsdParticle());
+ redefinedParticle->setTerm(item.redefinedGroup);
+ const XsdParticle::Ptr particle(new XsdParticle());
+ particle->setTerm(item.group);
+
+ // so that we can pass them to XsdParticleChecker::subsumes()
+ QString errorMsg;
+ if (!XsdParticleChecker::subsumes(particle, redefinedParticle, m_context, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("%1 element %2 is not a valid restriction of the %3 element it redefines: %4.")
+ .arg(formatElement("group"))
+ .arg(formatData(item.redefinedGroup->displayName(m_namePool)))
+ .arg(formatElement("group"))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(item.redefinedGroup));
+ return;
+ }
+ }
+}
+
+void XsdSchemaResolver::checkRedefinedAttributeGroups()
+{
+ for (int i = 0; i < m_redefinedAttributeGroups.count(); ++i) {
+ const RedefinedAttributeGroups item = m_redefinedAttributeGroups.at(i);
+
+ QString errorMsg;
+ if (!XsdSchemaHelper::isValidAttributeGroupRestriction(item.redefinedGroup, item.group, m_context, errorMsg)) {
+ m_context->error(QtXmlPatterns::tr("%1 element %2 is not a valid restriction of the %3 element it redefines: %4.")
+ .arg(formatElement("attributeGroup"))
+ .arg(formatData(item.redefinedGroup->displayName(m_namePool)))
+ .arg(formatElement("attributeGroup"))
+ .arg(errorMsg),
+ XsdSchemaContext::XSDError, sourceLocation(item.redefinedGroup));
+ return;
+ }
+ }
+}
+
+AnySimpleType::Ptr XsdSchemaResolver::findPrimitiveType(const AnySimpleType::Ptr &type, QSet<AnySimpleType::Ptr> &visitedTypes)
+{
+ if (visitedTypes.contains(type)) {
+ // found invalid circular reference...
+ return AnySimpleType::Ptr();
+ } else {
+ visitedTypes.insert(type);
+ }
+
+ const QXmlName typeName = type->name(m_namePool);
+ if (typeName == BuiltinTypes::xsString->name(m_namePool) ||
+ typeName == BuiltinTypes::xsBoolean->name(m_namePool) ||
+ typeName == BuiltinTypes::xsFloat->name(m_namePool) ||
+ typeName == BuiltinTypes::xsDouble->name(m_namePool) ||
+ typeName == BuiltinTypes::xsDecimal->name(m_namePool) ||
+ typeName == BuiltinTypes::xsDuration->name(m_namePool) ||
+ typeName == BuiltinTypes::xsDateTime->name(m_namePool) ||
+ typeName == BuiltinTypes::xsTime->name(m_namePool) ||
+ typeName == BuiltinTypes::xsDate->name(m_namePool) ||
+ typeName == BuiltinTypes::xsGYearMonth->name(m_namePool) ||
+ typeName == BuiltinTypes::xsGYear->name(m_namePool) ||
+ typeName == BuiltinTypes::xsGMonthDay->name(m_namePool) ||
+ typeName == BuiltinTypes::xsGDay->name(m_namePool) ||
+ typeName == BuiltinTypes::xsGMonth->name(m_namePool) ||
+ typeName == BuiltinTypes::xsHexBinary->name(m_namePool) ||
+ typeName == BuiltinTypes::xsBase64Binary->name(m_namePool) ||
+ typeName == BuiltinTypes::xsAnyURI->name(m_namePool) ||
+ typeName == BuiltinTypes::xsQName->name(m_namePool) ||
+ typeName == BuiltinTypes::xsNOTATION->name(m_namePool) ||
+ typeName == BuiltinTypes::xsAnySimpleType->name(m_namePool))
+ return type;
+ else {
+ if (type->wxsSuperType())
+ return findPrimitiveType(type->wxsSuperType(), visitedTypes);
+ else {
+ return AnySimpleType::Ptr();
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschemaresolver_p.h b/src/xmlpatterns/schema/qxsdschemaresolver_p.h
new file mode 100644
index 0000000..ef0154b
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschemaresolver_p.h
@@ -0,0 +1,578 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSchemaResolver_H
+#define Patternist_XsdSchemaResolver_H
+
+#include "qnamespacesupport_p.h"
+#include "qschematype_p.h"
+#include "qschematypefactory_p.h"
+#include "qxsdalternative_p.h"
+#include "qxsdattribute_p.h"
+#include "qxsdattributegroup_p.h"
+#include "qxsdelement_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdnotation_p.h"
+#include "qxsdreference_p.h"
+#include "qxsdschema_p.h"
+#include "qxsdschemachecker_p.h"
+#include "qxsdsimpletype_p.h"
+
+#include <QtCore/QExplicitlySharedDataPointer>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class XsdSchemaContext;
+ class XsdSchemaParserContext;
+
+ /**
+ * @short Encapsulates the resolving of type/element references in a schema after parsing has finished.
+ *
+ * This class collects task for resolving types or element references. After the parsing has finished,
+ * one can start the resolve process by calling resolve().
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaResolver : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdSchemaResolver> Ptr;
+
+ /**
+ * Creates a new schema resolver.
+ *
+ * @param context The schema context used for error reporting etc..
+ * @param parserContext The schema parser context where all objects to resolve belong to.
+ */
+ XsdSchemaResolver(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext);
+
+ /**
+ * Destroys the schema resolver.
+ */
+ ~XsdSchemaResolver();
+
+ /**
+ * Starts the resolve process.
+ */
+ void resolve();
+
+ /**
+ * Adds a resolve task for key references.
+ *
+ * The resolver will try to set the referencedKey property of @p keyRef to the <em>key</em> or <em>unique</em> object
+ * of @p element that has the given @p name.
+ */
+ void addKeyReference(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &keyRef, const QXmlName &name, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the base type of restriction of a simple type.
+ *
+ * The resolver will set the base type of @p simpleType to the type named by @p baseName.
+ */
+ void addSimpleRestrictionBase(const XsdSimpleType::Ptr &simpleType, const QXmlName &baseName, const QSourceLocation &location);
+
+ /**
+ * Removes the resolve task for the base type of restriction of the simple @p type.
+ */
+ void removeSimpleRestrictionBase(const XsdSimpleType::Ptr &type);
+
+ /**
+ * Adds a resolve task for the list type of a simple type.
+ *
+ * The resolver will set the itemType property of @p simpleType to the type named by @p typeName.
+ */
+ void addSimpleListType(const XsdSimpleType::Ptr &simpleType, const QXmlName &typeName, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the member types of a simple type.
+ *
+ * The resolver will set the memberTypes property of @p simpleType to the types named by @p typeNames.
+ */
+ void addSimpleUnionTypes(const XsdSimpleType::Ptr &simpleType, const QList<QXmlName> &typeNames, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the type of an element.
+ *
+ * The resolver will set the type of the @p element to the type named by @p typeName.
+ */
+ void addElementType(const XsdElement::Ptr &element, const QXmlName &typeName, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the base type of a complex type.
+ *
+ * The resolver will set the base type of @p complexType to the type named by @p baseName.
+ */
+ void addComplexBaseType(const XsdComplexType::Ptr &complexType, const QXmlName &baseName, const QSourceLocation &location, const XsdFacet::Hash &facets = XsdFacet::Hash());
+
+ /**
+ * Removes the resolve task for the base type of the complex @p type.
+ */
+ void removeComplexBaseType(const XsdComplexType::Ptr &type);
+
+ /**
+ * Adds a resolve task for the content type of a complex type.
+ *
+ * The resolver will set the content type properties for @p complexType based on the
+ * given explicit @p content and effective @p mixed value.
+ */
+ void addComplexContentType(const XsdComplexType::Ptr &complexType, const XsdParticle::Ptr &content, bool mixed);
+
+ /**
+ * Adds a resolve task for the type of an attribute.
+ *
+ * The resolver will set the type of the @p attribute to the type named by @p typeName.
+ */
+ void addAttributeType(const XsdAttribute::Ptr &attribute, const QXmlName &typeName, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the type of an alternative.
+ *
+ * The resolver will set the type of the @p alternative to the type named by @p typeName.
+ */
+ void addAlternativeType(const XsdAlternative::Ptr &alternative, const QXmlName &typeName, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for the type of an alternative.
+ *
+ * The resolver will set the type of the @p alternative to the type of the @p element after
+ * the type of the @p element has been resolved.
+ */
+ void addAlternativeType(const XsdAlternative::Ptr &alternative, const XsdElement::Ptr &element);
+
+ /**
+ * Adds a resolve task for the substituion group affiliations of an element.
+ *
+ * The resolver will set the substitution group affiliations of the @p element to the
+ * top-level element named by @p elementNames.
+ */
+ void addSubstitutionGroupAffiliation(const XsdElement::Ptr &element, const QList<QXmlName> &elementName, const QSourceLocation &location);
+
+ /**
+ * Adds a resolve task for an element that has no type specified, only a substitution group
+ * affiliation.
+ *
+ * The resolver will set the type of the substitution group affiliation as type for the element.
+ */
+ void addSubstitutionGroupType(const XsdElement::Ptr &element);
+
+ /**
+ * Adds the component location hash, so the resolver is able to report meaning full
+ * error messages.
+ */
+ void addComponentLocationHash(const QHash<NamedSchemaComponent::Ptr, QSourceLocation> &hash);
+
+ /**
+ * Add a resolve task for enumeration facet values.
+ *
+ * In case the enumeration is of type QName or NOTATION, we have to resolve the QName later,
+ * so we store the namespace bindings together with the facet value here and resolve it as soon as
+ * we have all type information available.
+ */
+ void addEnumerationFacetValue(const AtomicValue::Ptr &facetValue, const NamespaceSupport &namespaceSupport);
+
+ /**
+ * Add a check job for redefined groups.
+ *
+ * When an element group is redefined, we have to check whether the redefined group is a valid
+ * restriction of the group it redefines. As we need all type information for that, we keep them
+ * here for later checking.
+ */
+ void addRedefinedGroups(const XsdModelGroup::Ptr &redefinedGroup, const XsdModelGroup::Ptr &group);
+
+ /**
+ * Add a check job for redefined attribute groups.
+ *
+ * When an attribute group is redefined, we have to check whether the redefined group is a valid
+ * restriction of the group it redefines. As we need all type information for that, we keep them
+ * here for later checking.
+ */
+ void addRedefinedAttributeGroups(const XsdAttributeGroup::Ptr &redefinedGroup, const XsdAttributeGroup::Ptr &group);
+
+ /**
+ * Adds a check for nested <em>all</em> groups.
+ */
+ void addAllGroupCheck(const XsdReference::Ptr &reference);
+
+ /**
+ * Copies the data to resolve to an @p other resolver.
+ *
+ * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser.
+ */
+ void copyDataTo(const XsdSchemaResolver::Ptr &other) const;
+
+ /**
+ * Returns the to resolve base type name for the given @p type.
+ *
+ * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser.
+ */
+ QXmlName baseTypeNameOfType(const SchemaType::Ptr &type) const;
+
+ /**
+ * Returns the to resolve type name for the given @p attribute.
+ *
+ * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser.
+ */
+ QXmlName typeNameOfAttribute(const XsdAttribute::Ptr &attribute) const;
+
+ /**
+ * Sets the defaultOpenContent object from the schema parser.
+ */
+ void setDefaultOpenContent(const XsdComplexType::OpenContent::Ptr &openContent, bool appliesToEmpty);
+
+ private:
+ /**
+ * Resolves key references.
+ */
+ void resolveKeyReferences();
+
+ /**
+ * Resolves the base types of simple types derived by restriction.
+ */
+ void resolveSimpleRestrictionBaseTypes();
+
+ /**
+ * Resolves the other properties except the base type
+ * of all simple restrictions.
+ */
+ void resolveSimpleRestrictions();
+
+ /**
+ * Resolves the other properties except the base type
+ * of the given simple restriction.
+ *
+ * @param simpleType The restricted type to resolve.
+ * @param visitedTypes A set of already resolved types, used for termination of recursion.
+ */
+ void resolveSimpleRestrictions(const XsdSimpleType::Ptr &simpleType, QSet<XsdSimpleType::Ptr> &visitedTypes);
+
+ /**
+ * Resolves the item type property of simple types derived by list.
+ */
+ void resolveSimpleListType();
+
+ /**
+ * Resolves the member types property of simple types derived by union.
+ */
+ void resolveSimpleUnionTypes();
+
+ /**
+ * Resolves element types.
+ */
+ void resolveElementTypes();
+
+ /**
+ * Resolves base type of complex types.
+ */
+ void resolveComplexBaseTypes();
+
+ /**
+ * Resolves the simple content model of a complex type
+ * depending on its base type.
+ */
+ void resolveSimpleContentComplexTypes();
+
+ /**
+ * Resolves the complex content model of a complex type
+ * depending on its base type.
+ */
+ void resolveComplexContentComplexTypes();
+
+ /**
+ * Resolves the simple content model of a complex type
+ * depending on its base type.
+ *
+ * @param complexType The complex type to resolve.
+ * @param visitedTypes A set of already resolved types, used for termination of recursion.
+ */
+ void resolveSimpleContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes);
+
+ /**
+ * Resolves the complex content model of a complex type
+ * depending on its base type.
+ *
+ * @param complexType The complex type to resolve.
+ * @param visitedTypes A set of already resolved types, used for termination of recursion.
+ */
+ void resolveComplexContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes);
+
+ /**
+ * Resolves attribute types.
+ */
+ void resolveAttributeTypes();
+
+ /**
+ * Resolves alternative types.
+ */
+ void resolveAlternativeTypes();
+
+ /**
+ * Resolves substitution group affiliations.
+ */
+ void resolveSubstitutionGroupAffiliations();
+
+ /**
+ * Resolves substitution groups.
+ */
+ void resolveSubstitutionGroups();
+
+ /**
+ * Resolves all XsdReferences in the schema by their corresponding XsdElement or XsdModelGroup terms.
+ */
+ void resolveTermReferences();
+
+ /**
+ * Resolves all XsdReferences in the @p particle recursive by their corresponding XsdElement or XsdModelGroup terms.
+ */
+ void resolveTermReference(const XsdParticle::Ptr &particle, QSet<QXmlName> visitedGroups);
+
+ /**
+ * Resolves all XsdAttributeReferences in the schema by their corresponding XsdAttributeUse objects.
+ */
+ void resolveAttributeTermReferences();
+
+ /**
+ * Resolves all XsdAttributeReferences in the list of @p attributeUses by their corresponding XsdAttributeUse objects.
+ */
+ XsdAttributeUse::List resolveAttributeTermReferences(const XsdAttributeUse::List &attributeUses, XsdWildcard::Ptr &wildcard, QSet<QXmlName> visitedAttributeGroups);
+
+ /**
+ * Resolves the attribute inheritance of complex types.
+ *
+ * @note This method must be called after all base types have been resolved.
+ */
+ void resolveAttributeInheritance();
+
+ /**
+ * Resolves the attribute inheritance of the given complex types.
+ *
+ * @param complexType The complex type to resolve.
+ * @param visitedTypes A set of already resolved types, used for termination of recursion.
+ *
+ * @note This method must be called after all base types have been resolved.
+ */
+ void resolveAttributeInheritance(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes);
+
+ /**
+ * Resolves the enumeration facet values for QName and NOTATION based facets.
+ */
+ void resolveEnumerationFacetValues();
+
+ /**
+ * Returns the source location of the given schema @p component or a dummy
+ * source location if the component is not found in the component location hash.
+ */
+ QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr component) const;
+
+ /**
+ * Returns the facets that are marked for the given complex @p type with a simple
+ * type restriction.
+ */
+ XsdFacet::Hash complexTypeFacets(const XsdComplexType::Ptr &complexType) const;
+
+ /**
+ * Finds the primitive type for the given simple @p type.
+ *
+ * The type is found by walking up the inheritance tree, until one of the builtin
+ * primitive type definitions is reached.
+ */
+ AnySimpleType::Ptr findPrimitiveType(const AnySimpleType::Ptr &type, QSet<AnySimpleType::Ptr> &visitedTypes);
+
+ /**
+ * Checks the redefined groups.
+ */
+ void checkRedefinedGroups();
+
+ /**
+ * Checks the redefined attribute groups.
+ */
+ void checkRedefinedAttributeGroups();
+
+ class KeyReference
+ {
+ public:
+ XsdElement::Ptr element;
+ XsdIdentityConstraint::Ptr keyRef;
+ QXmlName reference;
+ QSourceLocation location;
+ };
+
+ class SimpleRestrictionBase
+ {
+ public:
+ XsdSimpleType::Ptr simpleType;
+ QXmlName baseName;
+ QSourceLocation location;
+ };
+
+ class SimpleListType
+ {
+ public:
+ XsdSimpleType::Ptr simpleType;
+ QXmlName typeName;
+ QSourceLocation location;
+ };
+
+ class SimpleUnionType
+ {
+ public:
+ XsdSimpleType::Ptr simpleType;
+ QList<QXmlName> typeNames;
+ QSourceLocation location;
+ };
+
+ class ElementType
+ {
+ public:
+ XsdElement::Ptr element;
+ QXmlName typeName;
+ QSourceLocation location;
+ };
+
+ class ComplexBaseType
+ {
+ public:
+ XsdComplexType::Ptr complexType;
+ QXmlName baseName;
+ QSourceLocation location;
+ XsdFacet::Hash facets;
+ };
+
+ class ComplexContentType
+ {
+ public:
+ XsdComplexType::Ptr complexType;
+ XsdParticle::Ptr explicitContent;
+ bool effectiveMixed;
+ };
+
+ class AttributeType
+ {
+ public:
+ XsdAttribute::Ptr attribute;
+ QXmlName typeName;
+ QSourceLocation location;
+ };
+
+ class AlternativeType
+ {
+ public:
+ XsdAlternative::Ptr alternative;
+ QXmlName typeName;
+ QSourceLocation location;
+ };
+
+ class AlternativeTypeElement
+ {
+ public:
+ XsdAlternative::Ptr alternative;
+ XsdElement::Ptr element;
+ };
+
+ class SubstitutionGroupAffiliation
+ {
+ public:
+ XsdElement::Ptr element;
+ QList<QXmlName> elementNames;
+ QSourceLocation location;
+ };
+
+ class RedefinedGroups
+ {
+ public:
+ XsdModelGroup::Ptr redefinedGroup;
+ XsdModelGroup::Ptr group;
+ };
+
+ class RedefinedAttributeGroups
+ {
+ public:
+ XsdAttributeGroup::Ptr redefinedGroup;
+ XsdAttributeGroup::Ptr group;
+ };
+
+ QVector<KeyReference> m_keyReferences;
+ QVector<SimpleRestrictionBase> m_simpleRestrictionBases;
+ QVector<SimpleListType> m_simpleListTypes;
+ QVector<SimpleUnionType> m_simpleUnionTypes;
+ QVector<ElementType> m_elementTypes;
+ QVector<ComplexBaseType> m_complexBaseTypes;
+ QVector<ComplexContentType> m_complexContentTypes;
+ QVector<AttributeType> m_attributeTypes;
+ QVector<AlternativeType> m_alternativeTypes;
+ QVector<AlternativeTypeElement> m_alternativeTypeElements;
+ QVector<SubstitutionGroupAffiliation> m_substitutionGroupAffiliations;
+ QVector<XsdElement::Ptr> m_substitutionGroupTypes;
+ QVector<RedefinedGroups> m_redefinedGroups;
+ QVector<RedefinedAttributeGroups> m_redefinedAttributeGroups;
+ QHash<AtomicValue::Ptr, NamespaceSupport> m_enumerationFacetValues;
+ QSet<XsdReference::Ptr> m_allGroups;
+
+ QExplicitlySharedDataPointer<XsdSchemaContext> m_context;
+ QExplicitlySharedDataPointer<XsdSchemaChecker> m_checker;
+ NamePool::Ptr m_namePool;
+ XsdSchema::Ptr m_schema;
+ QHash<NamedSchemaComponent::Ptr, QSourceLocation> m_componentLocationHash;
+ XsdComplexType::OpenContent::Ptr m_defaultOpenContent;
+ bool m_defaultOpenContentAppliesToEmpty;
+ SchemaType::List m_predefinedSchemaTypes;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschematoken.cpp b/src/xmlpatterns/schema/qxsdschematoken.cpp
new file mode 100644
index 0000000..a04f8ae
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschematoken.cpp
@@ -0,0 +1,2981 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */
+
+#include "qxsdschematoken_p.h"
+
+QT_BEGIN_NAMESPACE
+
+XsdSchemaToken::NodeName XsdSchemaToken::classifier2(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 100
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Id;
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier3(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+ if (data[1] == 108)
+
+
+ {
+
+ if(data[2] == 108)
+
+
+ return All;
+
+ }
+
+ else if (data[1] == 110)
+
+
+ {
+
+ if(data[2] == 121)
+
+
+ return Any;
+
+ }
+
+
+ }
+
+ else if (data[0] == 107)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 121
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Key;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Ref;
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Use;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier4(const QChar *data)
+
+ {
+ if (data[0] == 98)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Base;
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 114, 109
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Form;
+
+ }
+
+ else if (data[0] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 115, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return List;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Mode;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 109, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Name;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+ if (data[1] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 116
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Test;
+
+ }
+
+ else if (data[1] == 121)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Type;
+
+ }
+
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier5(const QChar *data)
+
+ {
+ if (data[0] == 98)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 111, 99, 107
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Block;
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+ if (data[1] == 105)
+
+
+ {
+ if (data[2] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 100
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Field;
+
+ }
+
+ else if (data[2] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 108
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Final;
+
+ }
+
+ else if (data[2] == 120)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 100
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Fixed;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 103)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 111, 117, 112
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Group;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 120, 101, 100
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Mixed;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102, 101, 114
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Refer;
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Union;
+
+ }
+
+ else if (data[0] == 118)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 108, 117, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Value;
+
+ }
+
+ else if (data[0] == 120)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 97, 116, 104
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Xpath;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier6(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 115, 101, 114, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Assert;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 111, 105, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Choice;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 109, 112, 111, 114, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Import;
+
+ }
+
+ else if (data[0] == 107)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 121, 114, 101, 102
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Keyref;
+
+ }
+
+ else if (data[0] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 110, 103, 116, 104
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Length;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 98, 108, 105, 99
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Public;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+ if (data[1] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 101, 109, 97
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Schema;
+
+ }
+
+ else if (data[1] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 114, 99, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Source;
+
+ }
+
+ else if (data[1] == 121)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 116, 101, 109
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return System;
+
+ }
+
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 105, 113, 117, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Unique;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier7(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 112, 105, 110, 102, 111
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Appinfo;
+
+ }
+
+ else if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102, 97, 117, 108, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Default;
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 101, 109, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Element;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 108, 117, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Include;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 116, 116, 101, 114, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Pattern;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 112, 108, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Replace;
+
+ }
+
+ else if (data[0] == 118)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 114, 115, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Version;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier8(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 98, 115, 116, 114, 97, 99, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Abstract;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 108, 108, 97, 112, 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Collapse;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 101, 109, 84, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return ItemType;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+ if (data[1] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 108, 97, 98, 108, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Nillable;
+
+ }
+
+ else if (data[1] == 111)
+
+
+ {
+ if (data[2] == 116)
+
+
+ {
+ if (data[3] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 105, 111, 110
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Notation;
+
+ }
+
+ else if (data[3] == 81)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 78, 97, 109, 101
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 4) == 0)
+
+
+ return NotQName;
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 118, 101, 114, 114, 105, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Override;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 101, 115, 101, 114, 118, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Preserve;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 100, 101, 102, 105, 110, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Redefine;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+ if (data[1] == 101)
+
+
+ {
+ if (data[2] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 99, 116, 111, 114
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Selector;
+
+ }
+
+ else if (data[2] == 113)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 101, 110, 99, 101
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Sequence;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 120)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 109, 108, 58, 108, 97, 110, 103
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return XmlLanguage;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier9(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+ if (data[1] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 101, 114, 116, 105, 111, 110
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Assertion;
+
+ }
+
+ else if (data[1] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 114, 105, 98, 117, 116, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Attribute;
+
+ }
+
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 120, 116, 101, 110, 115, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Extension;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+ if (data[1] == 97)
+
+
+ {
+ if (data[2] == 120)
+
+
+ {
+ if (data[3] == 76)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 110, 103, 116, 104
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0)
+
+
+ return MaxLength;
+
+ }
+
+ else if (data[3] == 79)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 99, 99, 117, 114, 115
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0)
+
+
+ return MaxOccurs;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[1] == 105)
+
+
+ {
+ if (data[2] == 110)
+
+
+ {
+ if (data[3] == 76)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 110, 103, 116, 104
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0)
+
+
+ return MinLength;
+
+ }
+
+ else if (data[3] == 79)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 99, 99, 117, 114, 115
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0)
+
+
+ return MinOccurs;
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Namespace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier10(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 110, 111, 116, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return Annotation;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 109, 112, 108, 101, 84, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return SimpleType;
+
+ }
+
+ else if (data[0] == 119)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 105, 116, 101, 83, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return WhiteSpace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier11(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 116, 101, 114, 110, 97, 116, 105, 118, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return Alternative;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 109, 112, 108, 101, 120, 84, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return ComplexType;
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 117, 109, 101, 114, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return Enumeration;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 109, 98, 101, 114, 84, 121, 112, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return MemberTypes;
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 101, 110, 67, 111, 110, 116, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return OpenContent;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 115, 116, 114, 105, 99, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return Restriction;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 116, 97, 108, 68, 105, 103, 105, 116, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0)
+
+
+ return TotalDigits;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier12(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 121, 65, 116, 116, 114, 105, 98, 117, 116, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0)
+
+
+ return AnyAttribute;
+
+ }
+
+ else if (data[0] == 98)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 111, 99, 107, 68, 101, 102, 97, 117, 108, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0)
+
+
+ return BlockDefault;
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 110, 97, 108, 68, 101, 102, 97, 117, 108, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0)
+
+
+ return FinalDefault;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+ if (data[1] == 97)
+
+
+ {
+ if (data[2] == 120)
+
+
+ {
+ if (data[3] == 69)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 120, 99, 108, 117, 115, 105, 118, 101
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0)
+
+
+ return MaxExclusive;
+
+ }
+
+ else if (data[3] == 73)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 108, 117, 115, 105, 118, 101
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0)
+
+
+ return MaxInclusive;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[1] == 105)
+
+
+ {
+ if (data[2] == 110)
+
+
+ {
+ if (data[3] == 69)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 120, 99, 108, 117, 115, 105, 118, 101
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0)
+
+
+ return MinExclusive;
+
+ }
+
+ else if (data[3] == 73)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 108, 117, 115, 105, 118, 101
+ };
+ if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0)
+
+
+ return MinInclusive;
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0)
+
+
+ return NotNamespace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier13(const QChar *data)
+
+ {
+ if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0)
+
+
+ return Documentation;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 109, 112, 108, 101, 67, 111, 110, 116, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0)
+
+
+ return SimpleContent;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier14(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+ if (data[1] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 108, 105, 101, 115, 84, 111, 69, 109, 112, 116, 121
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 12) == 0)
+
+
+ return AppliesToEmpty;
+
+ }
+
+ else if (data[1] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 114, 105, 98, 117, 116, 101, 71, 114, 111, 117, 112
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 12) == 0)
+
+
+ return AttributeGroup;
+
+ }
+
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 109, 112, 108, 101, 120, 67, 111, 110, 116, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return ComplexContent;
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 97, 99, 116, 105, 111, 110, 68, 105, 103, 105, 116, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return FractionDigits;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 99, 104, 101, 109, 97, 76, 111, 99, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return SchemaLocation;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier15(const QChar *data)
+
+ {
+ if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 111, 99, 101, 115, 115, 67, 111, 110, 116, 101, 110, 116, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return ProcessContents;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 114, 103, 101, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return TargetNamespace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier17(const QChar *data)
+
+ {
+ if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 16) == 0)
+
+
+ return DefaultAttributes;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 98, 115, 116, 105, 116, 117, 116, 105, 111, 110, 71, 114, 111, 117, 112
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 16) == 0)
+
+
+ return SubstitutionGroup;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier18(const QChar *data)
+
+ {
+ if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102, 97, 117, 108, 116, 79, 112, 101, 110, 67, 111, 110, 116, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return DefaultOpenContent;
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 101, 109, 101, 110, 116, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return ElementFormDefault;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier20(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 20) == 0)
+
+
+ return AttributeFormDefault;
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier21(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 120, 112, 97, 116, 104, 68, 101, 102, 97, 117, 108, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 21) == 0)
+
+
+ return XPathDefaultNamespace;
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier22(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 65, 112, 112, 108, 121
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 22) == 0)
+
+
+ return DefaultAttributesApply;
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::classifier32(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 32) == 0)
+
+
+ return XML_NS_SCHEMA_URI;
+
+
+ return NoKeyword;
+ }
+ XsdSchemaToken::NodeName XsdSchemaToken::toToken(const QChar *data, int length)
+ {
+ switch(length)
+ {
+
+ case 2:
+ return classifier2(data);
+
+
+ case 3:
+ return classifier3(data);
+
+
+ case 4:
+ return classifier4(data);
+
+
+ case 5:
+ return classifier5(data);
+
+
+ case 6:
+ return classifier6(data);
+
+
+ case 7:
+ return classifier7(data);
+
+
+ case 8:
+ return classifier8(data);
+
+
+ case 9:
+ return classifier9(data);
+
+
+ case 10:
+ return classifier10(data);
+
+
+ case 11:
+ return classifier11(data);
+
+
+ case 12:
+ return classifier12(data);
+
+
+ case 13:
+ return classifier13(data);
+
+
+ case 14:
+ return classifier14(data);
+
+
+ case 15:
+ return classifier15(data);
+
+
+ case 17:
+ return classifier17(data);
+
+
+ case 18:
+ return classifier18(data);
+
+
+ case 20:
+ return classifier20(data);
+
+
+ case 21:
+ return classifier21(data);
+
+
+ case 22:
+ return classifier22(data);
+
+
+ case 32:
+ return classifier32(data);
+
+
+ default:
+ return NoKeyword;
+ }
+ }
+
+
+ QString XsdSchemaToken::toString(NodeName token)
+ {
+ const unsigned short *data = 0;
+ int length = 0;
+
+ switch(token)
+ {
+
+ case Abstract:
+ {
+ static const unsigned short staticallyStoredAbstract[] =
+ {
+ 97, 98, 115, 116, 114, 97, 99, 116, 0
+ };
+ data = staticallyStoredAbstract;
+ length = 8;
+ break;
+ }
+
+ case All:
+ {
+ static const unsigned short staticallyStoredAll[] =
+ {
+ 97, 108, 108, 0
+ };
+ data = staticallyStoredAll;
+ length = 3;
+ break;
+ }
+
+ case Alternative:
+ {
+ static const unsigned short staticallyStoredAlternative[] =
+ {
+ 97, 108, 116, 101, 114, 110, 97, 116, 105, 118, 101, 0
+ };
+ data = staticallyStoredAlternative;
+ length = 11;
+ break;
+ }
+
+ case Annotation:
+ {
+ static const unsigned short staticallyStoredAnnotation[] =
+ {
+ 97, 110, 110, 111, 116, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredAnnotation;
+ length = 10;
+ break;
+ }
+
+ case Any:
+ {
+ static const unsigned short staticallyStoredAny[] =
+ {
+ 97, 110, 121, 0
+ };
+ data = staticallyStoredAny;
+ length = 3;
+ break;
+ }
+
+ case AnyAttribute:
+ {
+ static const unsigned short staticallyStoredAnyAttribute[] =
+ {
+ 97, 110, 121, 65, 116, 116, 114, 105, 98, 117, 116, 101, 0
+ };
+ data = staticallyStoredAnyAttribute;
+ length = 12;
+ break;
+ }
+
+ case Appinfo:
+ {
+ static const unsigned short staticallyStoredAppinfo[] =
+ {
+ 97, 112, 112, 105, 110, 102, 111, 0
+ };
+ data = staticallyStoredAppinfo;
+ length = 7;
+ break;
+ }
+
+ case AppliesToEmpty:
+ {
+ static const unsigned short staticallyStoredAppliesToEmpty[] =
+ {
+ 97, 112, 112, 108, 105, 101, 115, 84, 111, 69, 109, 112, 116, 121, 0
+ };
+ data = staticallyStoredAppliesToEmpty;
+ length = 14;
+ break;
+ }
+
+ case Assert:
+ {
+ static const unsigned short staticallyStoredAssert[] =
+ {
+ 97, 115, 115, 101, 114, 116, 0
+ };
+ data = staticallyStoredAssert;
+ length = 6;
+ break;
+ }
+
+ case Assertion:
+ {
+ static const unsigned short staticallyStoredAssertion[] =
+ {
+ 97, 115, 115, 101, 114, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredAssertion;
+ length = 9;
+ break;
+ }
+
+ case Attribute:
+ {
+ static const unsigned short staticallyStoredAttribute[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 0
+ };
+ data = staticallyStoredAttribute;
+ length = 9;
+ break;
+ }
+
+ case AttributeFormDefault:
+ {
+ static const unsigned short staticallyStoredAttributeFormDefault[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116, 0
+ };
+ data = staticallyStoredAttributeFormDefault;
+ length = 20;
+ break;
+ }
+
+ case AttributeGroup:
+ {
+ static const unsigned short staticallyStoredAttributeGroup[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 71, 114, 111, 117, 112, 0
+ };
+ data = staticallyStoredAttributeGroup;
+ length = 14;
+ break;
+ }
+
+ case Base:
+ {
+ static const unsigned short staticallyStoredBase[] =
+ {
+ 98, 97, 115, 101, 0
+ };
+ data = staticallyStoredBase;
+ length = 4;
+ break;
+ }
+
+ case Block:
+ {
+ static const unsigned short staticallyStoredBlock[] =
+ {
+ 98, 108, 111, 99, 107, 0
+ };
+ data = staticallyStoredBlock;
+ length = 5;
+ break;
+ }
+
+ case BlockDefault:
+ {
+ static const unsigned short staticallyStoredBlockDefault[] =
+ {
+ 98, 108, 111, 99, 107, 68, 101, 102, 97, 117, 108, 116, 0
+ };
+ data = staticallyStoredBlockDefault;
+ length = 12;
+ break;
+ }
+
+ case Choice:
+ {
+ static const unsigned short staticallyStoredChoice[] =
+ {
+ 99, 104, 111, 105, 99, 101, 0
+ };
+ data = staticallyStoredChoice;
+ length = 6;
+ break;
+ }
+
+ case Collapse:
+ {
+ static const unsigned short staticallyStoredCollapse[] =
+ {
+ 99, 111, 108, 108, 97, 112, 115, 101, 0
+ };
+ data = staticallyStoredCollapse;
+ length = 8;
+ break;
+ }
+
+ case ComplexContent:
+ {
+ static const unsigned short staticallyStoredComplexContent[] =
+ {
+ 99, 111, 109, 112, 108, 101, 120, 67, 111, 110, 116, 101, 110, 116, 0
+ };
+ data = staticallyStoredComplexContent;
+ length = 14;
+ break;
+ }
+
+ case ComplexType:
+ {
+ static const unsigned short staticallyStoredComplexType[] =
+ {
+ 99, 111, 109, 112, 108, 101, 120, 84, 121, 112, 101, 0
+ };
+ data = staticallyStoredComplexType;
+ length = 11;
+ break;
+ }
+
+ case Default:
+ {
+ static const unsigned short staticallyStoredDefault[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 0
+ };
+ data = staticallyStoredDefault;
+ length = 7;
+ break;
+ }
+
+ case DefaultAttributes:
+ {
+ static const unsigned short staticallyStoredDefaultAttributes[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 0
+ };
+ data = staticallyStoredDefaultAttributes;
+ length = 17;
+ break;
+ }
+
+ case DefaultAttributesApply:
+ {
+ static const unsigned short staticallyStoredDefaultAttributesApply[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 65, 112, 112, 108, 121, 0
+ };
+ data = staticallyStoredDefaultAttributesApply;
+ length = 22;
+ break;
+ }
+
+ case DefaultOpenContent:
+ {
+ static const unsigned short staticallyStoredDefaultOpenContent[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 79, 112, 101, 110, 67, 111, 110, 116, 101, 110, 116, 0
+ };
+ data = staticallyStoredDefaultOpenContent;
+ length = 18;
+ break;
+ }
+
+ case Documentation:
+ {
+ static const unsigned short staticallyStoredDocumentation[] =
+ {
+ 100, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredDocumentation;
+ length = 13;
+ break;
+ }
+
+ case Element:
+ {
+ static const unsigned short staticallyStoredElement[] =
+ {
+ 101, 108, 101, 109, 101, 110, 116, 0
+ };
+ data = staticallyStoredElement;
+ length = 7;
+ break;
+ }
+
+ case ElementFormDefault:
+ {
+ static const unsigned short staticallyStoredElementFormDefault[] =
+ {
+ 101, 108, 101, 109, 101, 110, 116, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116, 0
+ };
+ data = staticallyStoredElementFormDefault;
+ length = 18;
+ break;
+ }
+
+ case Enumeration:
+ {
+ static const unsigned short staticallyStoredEnumeration[] =
+ {
+ 101, 110, 117, 109, 101, 114, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredEnumeration;
+ length = 11;
+ break;
+ }
+
+ case Extension:
+ {
+ static const unsigned short staticallyStoredExtension[] =
+ {
+ 101, 120, 116, 101, 110, 115, 105, 111, 110, 0
+ };
+ data = staticallyStoredExtension;
+ length = 9;
+ break;
+ }
+
+ case Field:
+ {
+ static const unsigned short staticallyStoredField[] =
+ {
+ 102, 105, 101, 108, 100, 0
+ };
+ data = staticallyStoredField;
+ length = 5;
+ break;
+ }
+
+ case Final:
+ {
+ static const unsigned short staticallyStoredFinal[] =
+ {
+ 102, 105, 110, 97, 108, 0
+ };
+ data = staticallyStoredFinal;
+ length = 5;
+ break;
+ }
+
+ case FinalDefault:
+ {
+ static const unsigned short staticallyStoredFinalDefault[] =
+ {
+ 102, 105, 110, 97, 108, 68, 101, 102, 97, 117, 108, 116, 0
+ };
+ data = staticallyStoredFinalDefault;
+ length = 12;
+ break;
+ }
+
+ case Fixed:
+ {
+ static const unsigned short staticallyStoredFixed[] =
+ {
+ 102, 105, 120, 101, 100, 0
+ };
+ data = staticallyStoredFixed;
+ length = 5;
+ break;
+ }
+
+ case Form:
+ {
+ static const unsigned short staticallyStoredForm[] =
+ {
+ 102, 111, 114, 109, 0
+ };
+ data = staticallyStoredForm;
+ length = 4;
+ break;
+ }
+
+ case FractionDigits:
+ {
+ static const unsigned short staticallyStoredFractionDigits[] =
+ {
+ 102, 114, 97, 99, 116, 105, 111, 110, 68, 105, 103, 105, 116, 115, 0
+ };
+ data = staticallyStoredFractionDigits;
+ length = 14;
+ break;
+ }
+
+ case Group:
+ {
+ static const unsigned short staticallyStoredGroup[] =
+ {
+ 103, 114, 111, 117, 112, 0
+ };
+ data = staticallyStoredGroup;
+ length = 5;
+ break;
+ }
+
+ case Id:
+ {
+ static const unsigned short staticallyStoredId[] =
+ {
+ 105, 100, 0
+ };
+ data = staticallyStoredId;
+ length = 2;
+ break;
+ }
+
+ case Import:
+ {
+ static const unsigned short staticallyStoredImport[] =
+ {
+ 105, 109, 112, 111, 114, 116, 0
+ };
+ data = staticallyStoredImport;
+ length = 6;
+ break;
+ }
+
+ case Include:
+ {
+ static const unsigned short staticallyStoredInclude[] =
+ {
+ 105, 110, 99, 108, 117, 100, 101, 0
+ };
+ data = staticallyStoredInclude;
+ length = 7;
+ break;
+ }
+
+ case ItemType:
+ {
+ static const unsigned short staticallyStoredItemType[] =
+ {
+ 105, 116, 101, 109, 84, 121, 112, 101, 0
+ };
+ data = staticallyStoredItemType;
+ length = 8;
+ break;
+ }
+
+ case Key:
+ {
+ static const unsigned short staticallyStoredKey[] =
+ {
+ 107, 101, 121, 0
+ };
+ data = staticallyStoredKey;
+ length = 3;
+ break;
+ }
+
+ case Keyref:
+ {
+ static const unsigned short staticallyStoredKeyref[] =
+ {
+ 107, 101, 121, 114, 101, 102, 0
+ };
+ data = staticallyStoredKeyref;
+ length = 6;
+ break;
+ }
+
+ case Length:
+ {
+ static const unsigned short staticallyStoredLength[] =
+ {
+ 108, 101, 110, 103, 116, 104, 0
+ };
+ data = staticallyStoredLength;
+ length = 6;
+ break;
+ }
+
+ case List:
+ {
+ static const unsigned short staticallyStoredList[] =
+ {
+ 108, 105, 115, 116, 0
+ };
+ data = staticallyStoredList;
+ length = 4;
+ break;
+ }
+
+ case MaxExclusive:
+ {
+ static const unsigned short staticallyStoredMaxExclusive[] =
+ {
+ 109, 97, 120, 69, 120, 99, 108, 117, 115, 105, 118, 101, 0
+ };
+ data = staticallyStoredMaxExclusive;
+ length = 12;
+ break;
+ }
+
+ case MaxInclusive:
+ {
+ static const unsigned short staticallyStoredMaxInclusive[] =
+ {
+ 109, 97, 120, 73, 110, 99, 108, 117, 115, 105, 118, 101, 0
+ };
+ data = staticallyStoredMaxInclusive;
+ length = 12;
+ break;
+ }
+
+ case MaxLength:
+ {
+ static const unsigned short staticallyStoredMaxLength[] =
+ {
+ 109, 97, 120, 76, 101, 110, 103, 116, 104, 0
+ };
+ data = staticallyStoredMaxLength;
+ length = 9;
+ break;
+ }
+
+ case MaxOccurs:
+ {
+ static const unsigned short staticallyStoredMaxOccurs[] =
+ {
+ 109, 97, 120, 79, 99, 99, 117, 114, 115, 0
+ };
+ data = staticallyStoredMaxOccurs;
+ length = 9;
+ break;
+ }
+
+ case MemberTypes:
+ {
+ static const unsigned short staticallyStoredMemberTypes[] =
+ {
+ 109, 101, 109, 98, 101, 114, 84, 121, 112, 101, 115, 0
+ };
+ data = staticallyStoredMemberTypes;
+ length = 11;
+ break;
+ }
+
+ case MinExclusive:
+ {
+ static const unsigned short staticallyStoredMinExclusive[] =
+ {
+ 109, 105, 110, 69, 120, 99, 108, 117, 115, 105, 118, 101, 0
+ };
+ data = staticallyStoredMinExclusive;
+ length = 12;
+ break;
+ }
+
+ case MinInclusive:
+ {
+ static const unsigned short staticallyStoredMinInclusive[] =
+ {
+ 109, 105, 110, 73, 110, 99, 108, 117, 115, 105, 118, 101, 0
+ };
+ data = staticallyStoredMinInclusive;
+ length = 12;
+ break;
+ }
+
+ case MinLength:
+ {
+ static const unsigned short staticallyStoredMinLength[] =
+ {
+ 109, 105, 110, 76, 101, 110, 103, 116, 104, 0
+ };
+ data = staticallyStoredMinLength;
+ length = 9;
+ break;
+ }
+
+ case MinOccurs:
+ {
+ static const unsigned short staticallyStoredMinOccurs[] =
+ {
+ 109, 105, 110, 79, 99, 99, 117, 114, 115, 0
+ };
+ data = staticallyStoredMinOccurs;
+ length = 9;
+ break;
+ }
+
+ case Mixed:
+ {
+ static const unsigned short staticallyStoredMixed[] =
+ {
+ 109, 105, 120, 101, 100, 0
+ };
+ data = staticallyStoredMixed;
+ length = 5;
+ break;
+ }
+
+ case Mode:
+ {
+ static const unsigned short staticallyStoredMode[] =
+ {
+ 109, 111, 100, 101, 0
+ };
+ data = staticallyStoredMode;
+ length = 4;
+ break;
+ }
+
+ case Name:
+ {
+ static const unsigned short staticallyStoredName[] =
+ {
+ 110, 97, 109, 101, 0
+ };
+ data = staticallyStoredName;
+ length = 4;
+ break;
+ }
+
+ case Namespace:
+ {
+ static const unsigned short staticallyStoredNamespace[] =
+ {
+ 110, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredNamespace;
+ length = 9;
+ break;
+ }
+
+ case Nillable:
+ {
+ static const unsigned short staticallyStoredNillable[] =
+ {
+ 110, 105, 108, 108, 97, 98, 108, 101, 0
+ };
+ data = staticallyStoredNillable;
+ length = 8;
+ break;
+ }
+
+ case NotNamespace:
+ {
+ static const unsigned short staticallyStoredNotNamespace[] =
+ {
+ 110, 111, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredNotNamespace;
+ length = 12;
+ break;
+ }
+
+ case NotQName:
+ {
+ static const unsigned short staticallyStoredNotQName[] =
+ {
+ 110, 111, 116, 81, 78, 97, 109, 101, 0
+ };
+ data = staticallyStoredNotQName;
+ length = 8;
+ break;
+ }
+
+ case Notation:
+ {
+ static const unsigned short staticallyStoredNotation[] =
+ {
+ 110, 111, 116, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredNotation;
+ length = 8;
+ break;
+ }
+
+ case OpenContent:
+ {
+ static const unsigned short staticallyStoredOpenContent[] =
+ {
+ 111, 112, 101, 110, 67, 111, 110, 116, 101, 110, 116, 0
+ };
+ data = staticallyStoredOpenContent;
+ length = 11;
+ break;
+ }
+
+ case Override:
+ {
+ static const unsigned short staticallyStoredOverride[] =
+ {
+ 111, 118, 101, 114, 114, 105, 100, 101, 0
+ };
+ data = staticallyStoredOverride;
+ length = 8;
+ break;
+ }
+
+ case Pattern:
+ {
+ static const unsigned short staticallyStoredPattern[] =
+ {
+ 112, 97, 116, 116, 101, 114, 110, 0
+ };
+ data = staticallyStoredPattern;
+ length = 7;
+ break;
+ }
+
+ case Preserve:
+ {
+ static const unsigned short staticallyStoredPreserve[] =
+ {
+ 112, 114, 101, 115, 101, 114, 118, 101, 0
+ };
+ data = staticallyStoredPreserve;
+ length = 8;
+ break;
+ }
+
+ case ProcessContents:
+ {
+ static const unsigned short staticallyStoredProcessContents[] =
+ {
+ 112, 114, 111, 99, 101, 115, 115, 67, 111, 110, 116, 101, 110, 116, 115, 0
+ };
+ data = staticallyStoredProcessContents;
+ length = 15;
+ break;
+ }
+
+ case Public:
+ {
+ static const unsigned short staticallyStoredPublic[] =
+ {
+ 112, 117, 98, 108, 105, 99, 0
+ };
+ data = staticallyStoredPublic;
+ length = 6;
+ break;
+ }
+
+ case Redefine:
+ {
+ static const unsigned short staticallyStoredRedefine[] =
+ {
+ 114, 101, 100, 101, 102, 105, 110, 101, 0
+ };
+ data = staticallyStoredRedefine;
+ length = 8;
+ break;
+ }
+
+ case Ref:
+ {
+ static const unsigned short staticallyStoredRef[] =
+ {
+ 114, 101, 102, 0
+ };
+ data = staticallyStoredRef;
+ length = 3;
+ break;
+ }
+
+ case Refer:
+ {
+ static const unsigned short staticallyStoredRefer[] =
+ {
+ 114, 101, 102, 101, 114, 0
+ };
+ data = staticallyStoredRefer;
+ length = 5;
+ break;
+ }
+
+ case Replace:
+ {
+ static const unsigned short staticallyStoredReplace[] =
+ {
+ 114, 101, 112, 108, 97, 99, 101, 0
+ };
+ data = staticallyStoredReplace;
+ length = 7;
+ break;
+ }
+
+ case Restriction:
+ {
+ static const unsigned short staticallyStoredRestriction[] =
+ {
+ 114, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredRestriction;
+ length = 11;
+ break;
+ }
+
+ case Schema:
+ {
+ static const unsigned short staticallyStoredSchema[] =
+ {
+ 115, 99, 104, 101, 109, 97, 0
+ };
+ data = staticallyStoredSchema;
+ length = 6;
+ break;
+ }
+
+ case SchemaLocation:
+ {
+ static const unsigned short staticallyStoredSchemaLocation[] =
+ {
+ 115, 99, 104, 101, 109, 97, 76, 111, 99, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredSchemaLocation;
+ length = 14;
+ break;
+ }
+
+ case Selector:
+ {
+ static const unsigned short staticallyStoredSelector[] =
+ {
+ 115, 101, 108, 101, 99, 116, 111, 114, 0
+ };
+ data = staticallyStoredSelector;
+ length = 8;
+ break;
+ }
+
+ case Sequence:
+ {
+ static const unsigned short staticallyStoredSequence[] =
+ {
+ 115, 101, 113, 117, 101, 110, 99, 101, 0
+ };
+ data = staticallyStoredSequence;
+ length = 8;
+ break;
+ }
+
+ case SimpleContent:
+ {
+ static const unsigned short staticallyStoredSimpleContent[] =
+ {
+ 115, 105, 109, 112, 108, 101, 67, 111, 110, 116, 101, 110, 116, 0
+ };
+ data = staticallyStoredSimpleContent;
+ length = 13;
+ break;
+ }
+
+ case SimpleType:
+ {
+ static const unsigned short staticallyStoredSimpleType[] =
+ {
+ 115, 105, 109, 112, 108, 101, 84, 121, 112, 101, 0
+ };
+ data = staticallyStoredSimpleType;
+ length = 10;
+ break;
+ }
+
+ case Source:
+ {
+ static const unsigned short staticallyStoredSource[] =
+ {
+ 115, 111, 117, 114, 99, 101, 0
+ };
+ data = staticallyStoredSource;
+ length = 6;
+ break;
+ }
+
+ case SubstitutionGroup:
+ {
+ static const unsigned short staticallyStoredSubstitutionGroup[] =
+ {
+ 115, 117, 98, 115, 116, 105, 116, 117, 116, 105, 111, 110, 71, 114, 111, 117, 112, 0
+ };
+ data = staticallyStoredSubstitutionGroup;
+ length = 17;
+ break;
+ }
+
+ case System:
+ {
+ static const unsigned short staticallyStoredSystem[] =
+ {
+ 115, 121, 115, 116, 101, 109, 0
+ };
+ data = staticallyStoredSystem;
+ length = 6;
+ break;
+ }
+
+ case TargetNamespace:
+ {
+ static const unsigned short staticallyStoredTargetNamespace[] =
+ {
+ 116, 97, 114, 103, 101, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredTargetNamespace;
+ length = 15;
+ break;
+ }
+
+ case Test:
+ {
+ static const unsigned short staticallyStoredTest[] =
+ {
+ 116, 101, 115, 116, 0
+ };
+ data = staticallyStoredTest;
+ length = 4;
+ break;
+ }
+
+ case TotalDigits:
+ {
+ static const unsigned short staticallyStoredTotalDigits[] =
+ {
+ 116, 111, 116, 97, 108, 68, 105, 103, 105, 116, 115, 0
+ };
+ data = staticallyStoredTotalDigits;
+ length = 11;
+ break;
+ }
+
+ case Type:
+ {
+ static const unsigned short staticallyStoredType[] =
+ {
+ 116, 121, 112, 101, 0
+ };
+ data = staticallyStoredType;
+ length = 4;
+ break;
+ }
+
+ case Union:
+ {
+ static const unsigned short staticallyStoredUnion[] =
+ {
+ 117, 110, 105, 111, 110, 0
+ };
+ data = staticallyStoredUnion;
+ length = 5;
+ break;
+ }
+
+ case Unique:
+ {
+ static const unsigned short staticallyStoredUnique[] =
+ {
+ 117, 110, 105, 113, 117, 101, 0
+ };
+ data = staticallyStoredUnique;
+ length = 6;
+ break;
+ }
+
+ case Use:
+ {
+ static const unsigned short staticallyStoredUse[] =
+ {
+ 117, 115, 101, 0
+ };
+ data = staticallyStoredUse;
+ length = 3;
+ break;
+ }
+
+ case Value:
+ {
+ static const unsigned short staticallyStoredValue[] =
+ {
+ 118, 97, 108, 117, 101, 0
+ };
+ data = staticallyStoredValue;
+ length = 5;
+ break;
+ }
+
+ case Version:
+ {
+ static const unsigned short staticallyStoredVersion[] =
+ {
+ 118, 101, 114, 115, 105, 111, 110, 0
+ };
+ data = staticallyStoredVersion;
+ length = 7;
+ break;
+ }
+
+ case WhiteSpace:
+ {
+ static const unsigned short staticallyStoredWhiteSpace[] =
+ {
+ 119, 104, 105, 116, 101, 83, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredWhiteSpace;
+ length = 10;
+ break;
+ }
+
+ case XML_NS_SCHEMA_URI:
+ {
+ static const unsigned short staticallyStoredXML_NS_SCHEMA_URI[] =
+ {
+ 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97, 0
+ };
+ data = staticallyStoredXML_NS_SCHEMA_URI;
+ length = 32;
+ break;
+ }
+
+ case XPathDefaultNamespace:
+ {
+ static const unsigned short staticallyStoredXPathDefaultNamespace[] =
+ {
+ 120, 112, 97, 116, 104, 68, 101, 102, 97, 117, 108, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredXPathDefaultNamespace;
+ length = 21;
+ break;
+ }
+
+ case XmlLanguage:
+ {
+ static const unsigned short staticallyStoredXmlLanguage[] =
+ {
+ 120, 109, 108, 58, 108, 97, 110, 103, 0
+ };
+ data = staticallyStoredXmlLanguage;
+ length = 8;
+ break;
+ }
+
+ case Xpath:
+ {
+ static const unsigned short staticallyStoredXpath[] =
+ {
+ 120, 112, 97, 116, 104, 0
+ };
+ data = staticallyStoredXpath;
+ length = 5;
+ break;
+ }
+
+ default:
+ /* It's either the default token, or an undefined enum
+ * value. We silence a compiler warning, and return the
+ * empty string. */
+ ;
+ }
+
+ union
+ {
+ const unsigned short *data;
+ const QChar *asQChar;
+ } converter;
+ converter.data = data;
+
+ return QString::fromRawData(converter.asQChar, length);
+ }
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/schema/qxsdschematoken_p.h b/src/xmlpatterns/schema/qxsdschematoken_p.h
new file mode 100644
index 0000000..fbf71f0
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschematoken_p.h
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */
+
+#ifndef QPatternist_XsdSchemaToken_h
+#define QPatternist_XsdSchemaToken_h
+
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+class XsdSchemaToken
+ {
+ public:
+ enum NodeName
+
+ {
+ NoKeyword,
+Abstract,
+All,
+Alternative,
+Annotation,
+Any,
+AnyAttribute,
+Appinfo,
+AppliesToEmpty,
+Assert,
+Assertion,
+Attribute,
+AttributeFormDefault,
+AttributeGroup,
+Base,
+Block,
+BlockDefault,
+Choice,
+Collapse,
+ComplexContent,
+ComplexType,
+Default,
+DefaultAttributes,
+DefaultAttributesApply,
+DefaultOpenContent,
+Documentation,
+Element,
+ElementFormDefault,
+Enumeration,
+Extension,
+Field,
+Final,
+FinalDefault,
+Fixed,
+Form,
+FractionDigits,
+Group,
+Id,
+Import,
+Include,
+ItemType,
+Key,
+Keyref,
+Length,
+List,
+MaxExclusive,
+MaxInclusive,
+MaxLength,
+MaxOccurs,
+MemberTypes,
+MinExclusive,
+MinInclusive,
+MinLength,
+MinOccurs,
+Mixed,
+Mode,
+Name,
+Namespace,
+Nillable,
+NotNamespace,
+NotQName,
+Notation,
+OpenContent,
+Override,
+Pattern,
+Preserve,
+ProcessContents,
+Public,
+Redefine,
+Ref,
+Refer,
+Replace,
+Restriction,
+Schema,
+SchemaLocation,
+Selector,
+Sequence,
+SimpleContent,
+SimpleType,
+Source,
+SubstitutionGroup,
+System,
+TargetNamespace,
+Test,
+TotalDigits,
+Type,
+Union,
+Unique,
+Use,
+Value,
+Version,
+WhiteSpace,
+XML_NS_SCHEMA_URI,
+XPathDefaultNamespace,
+XmlLanguage,
+Xpath
+ };
+
+ static inline NodeName toToken(const QString &value);
+static inline NodeName toToken(const QStringRef &value);
+static NodeName toToken(const QChar *data, int length);
+static QString toString(NodeName token);
+
+
+ private:
+ static inline NodeName classifier2(const QChar *data);
+static inline NodeName classifier3(const QChar *data);
+static inline NodeName classifier4(const QChar *data);
+static inline NodeName classifier5(const QChar *data);
+static inline NodeName classifier6(const QChar *data);
+static inline NodeName classifier7(const QChar *data);
+static inline NodeName classifier8(const QChar *data);
+static inline NodeName classifier9(const QChar *data);
+static inline NodeName classifier10(const QChar *data);
+static inline NodeName classifier11(const QChar *data);
+static inline NodeName classifier12(const QChar *data);
+static inline NodeName classifier13(const QChar *data);
+static inline NodeName classifier14(const QChar *data);
+static inline NodeName classifier15(const QChar *data);
+static inline NodeName classifier17(const QChar *data);
+static inline NodeName classifier18(const QChar *data);
+static inline NodeName classifier20(const QChar *data);
+static inline NodeName classifier21(const QChar *data);
+static inline NodeName classifier22(const QChar *data);
+static inline NodeName classifier32(const QChar *data);
+
+ };
+
+ inline XsdSchemaToken::NodeName XsdSchemaToken::toToken(const QString &value)
+ {
+ return toToken(value.constData(), value.length());
+ }
+
+ inline XsdSchemaToken::NodeName XsdSchemaToken::toToken(const QStringRef &value)
+ {
+ return toToken(value.constData(), value.length());
+ }
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdschematypesfactory.cpp b/src/xmlpatterns/schema/qxsdschematypesfactory.cpp
new file mode 100644
index 0000000..b5f319b
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschematypesfactory.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdschematypesfactory_p.h"
+
+#include "qbasictypesfactory_p.h"
+#include "qbuiltintypes_p.h"
+#include "qderivedinteger_p.h"
+#include "qderivedstring_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qxsdschematoken_p.h"
+#include "qxsdsimpletype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaTypesFactory::XsdSchemaTypesFactory(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+{
+ m_types.reserve(3);
+
+ const XsdFacet::Ptr whiteSpaceFacet(new XsdFacet());
+ whiteSpaceFacet->setType(XsdFacet::WhiteSpace);
+ whiteSpaceFacet->setFixed(true);
+ whiteSpaceFacet->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse)));
+
+ const XsdFacet::Ptr minLengthFacet(new XsdFacet());
+ minLengthFacet->setType(XsdFacet::MinimumLength);
+ minLengthFacet->setValue(DerivedInteger<TypeNonNegativeInteger>::fromLexical(namePool, QLatin1String("1")));
+
+ XsdFacet::Hash facets;
+ facets.insert(whiteSpaceFacet->type(), whiteSpaceFacet);
+ facets.insert(minLengthFacet->type(), minLengthFacet);
+
+ {
+ const QXmlName typeName = m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("NMTOKENS"));
+ const XsdSimpleType::Ptr type(new XsdSimpleType());
+ type->setName(typeName);
+ type->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
+ type->setCategory(XsdSimpleType::SimpleTypeList);
+ type->setItemType(BuiltinTypes::xsNMTOKEN);
+ type->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+ type->setFacets(facets);
+ m_types.insert(typeName, type);
+ }
+ {
+ const QXmlName typeName = m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("IDREFS"));
+ const XsdSimpleType::Ptr type(new XsdSimpleType());
+ type->setName(typeName);
+ type->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
+ type->setCategory(XsdSimpleType::SimpleTypeList);
+ type->setItemType(BuiltinTypes::xsIDREF);
+ type->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+ type->setFacets(facets);
+ m_types.insert(typeName, type);
+ }
+ {
+ const QXmlName typeName = m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("ENTITIES"));
+ const XsdSimpleType::Ptr type(new XsdSimpleType());
+ type->setName(typeName);
+ type->setWxsSuperType(BuiltinTypes::xsAnySimpleType);
+ type->setCategory(XsdSimpleType::SimpleTypeList);
+ type->setItemType(BuiltinTypes::xsENTITY);
+ type->setDerivationMethod(XsdSimpleType::DerivationRestriction);
+ type->setFacets(facets);
+ m_types.insert(typeName, type);
+ }
+}
+
+SchemaType::Ptr XsdSchemaTypesFactory::createSchemaType(const QXmlName name) const
+{
+ if (m_types.contains(name)) {
+ return m_types.value(name);
+ } else {
+ if (!m_basicTypesFactory)
+ m_basicTypesFactory = BasicTypesFactory::self(m_namePool);
+
+ return m_basicTypesFactory->createSchemaType(name);
+ }
+}
+
+SchemaType::Hash XsdSchemaTypesFactory::types() const
+{
+ return m_types;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdschematypesfactory_p.h b/src/xmlpatterns/schema/qxsdschematypesfactory_p.h
new file mode 100644
index 0000000..74ecc3c
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdschematypesfactory_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSchemaTypesFactory_H
+#define Patternist_XsdSchemaTypesFactory_H
+
+#include <QtCore/QHash>
+#include "qschematypefactory_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Factory for creating schema types for the types defined in XSD.
+ *
+ * @ingroup Patternist_types
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSchemaTypesFactory : public SchemaTypeFactory
+ {
+ public:
+ /**
+ * Creates a new schema type factory.
+ *
+ * @param namePool The name pool all type names belong to.
+ */
+ XsdSchemaTypesFactory(const NamePool::Ptr &namePool);
+
+ /**
+ * Creates a primitive type for @p name. If @p name is not supported,
+ * @c null is returned.
+ *
+ * @note This does not handle user defined types, only builtin types.
+ */
+ virtual SchemaType::Ptr createSchemaType(const QXmlName) const;
+
+ /**
+ * Returns a hash of all available types.
+ */
+ virtual SchemaType::Hash types() const;
+
+ private:
+ /**
+ * A dictonary of all predefined schema types.
+ */
+ SchemaType::Hash m_types;
+
+ NamePool::Ptr m_namePool;
+ mutable SchemaTypeFactory::Ptr m_basicTypesFactory;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdsimpletype.cpp b/src/xmlpatterns/schema/qxsdsimpletype.cpp
new file mode 100644
index 0000000..6fd5658
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdsimpletype.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#include "qxsdsimpletype_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QString XsdSimpleType::displayName(const NamePool::Ptr &np) const
+{
+ return np->displayName(name(np));
+}
+
+void XsdSimpleType::setWxsSuperType(const SchemaType::Ptr &type)
+{
+ m_superType = type;
+}
+
+SchemaType::Ptr XsdSimpleType::wxsSuperType() const
+{
+ return m_superType;
+}
+
+void XsdSimpleType::setContext(const NamedSchemaComponent::Ptr &component)
+{
+ m_context = component;
+}
+
+NamedSchemaComponent::Ptr XsdSimpleType::context() const
+{
+ return m_context;
+}
+
+void XsdSimpleType::setPrimitiveType(const AnySimpleType::Ptr &type)
+{
+ m_primitiveType = type;
+}
+
+AnySimpleType::Ptr XsdSimpleType::primitiveType() const
+{
+ return m_primitiveType;
+}
+
+void XsdSimpleType::setItemType(const AnySimpleType::Ptr &type)
+{
+ m_itemType = type;
+}
+
+AnySimpleType::Ptr XsdSimpleType::itemType() const
+{
+ return m_itemType;
+}
+
+void XsdSimpleType::setMemberTypes(const AnySimpleType::List &types)
+{
+ m_memberTypes = types;
+}
+
+AnySimpleType::List XsdSimpleType::memberTypes() const
+{
+ return m_memberTypes;
+}
+
+void XsdSimpleType::setFacets(const XsdFacet::Hash &facets)
+{
+ m_facets = facets;
+}
+
+XsdFacet::Hash XsdSimpleType::facets() const
+{
+ return m_facets;
+}
+
+void XsdSimpleType::setCategory(TypeCategory category)
+{
+ m_typeCategory = category;
+}
+
+XsdSimpleType::TypeCategory XsdSimpleType::category() const
+{
+ return m_typeCategory;
+}
+
+void XsdSimpleType::setDerivationMethod(DerivationMethod method)
+{
+ m_derivationMethod = method;
+}
+
+XsdSimpleType::DerivationMethod XsdSimpleType::derivationMethod() const
+{
+ return m_derivationMethod;
+}
+
+bool XsdSimpleType::isDefinedBySchema() const
+{
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdsimpletype_p.h b/src/xmlpatterns/schema/qxsdsimpletype_p.h
new file mode 100644
index 0000000..6305fc7
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdsimpletype_p.h
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdSimpleType_H
+#define Patternist_XsdSimpleType_H
+
+#include "qanysimpletype_p.h"
+#include "qxsdfacet_p.h"
+#include "qxsduserschematype_p.h"
+
+#include <QtCore/QSet>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD simpleType object.
+ *
+ * This class represents the <em>simpleType</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema-2/#rf-defn">here</a>.
+ *
+ * It contains information from either a top-level simple type declaration (as child of a <em>schema</em> object)
+ * or a local simple type declaration (as descendant of an <em>element</em> or <em>complexType</em> object).
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSSimpleType">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdSimpleType : public XsdUserSchemaType<AnySimpleType>
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdSimpleType> Ptr;
+
+ /**
+ * Returns the display name of the simple type.
+ *
+ * @param namePool The name pool the type name is stored in.
+ */
+ virtual QString displayName(const NamePool::Ptr &namePool) const;
+
+ /**
+ * Sets the base @p type of the simple type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-basetype">Base Type Definition</a>
+ */
+ void setWxsSuperType(const SchemaType::Ptr &type);
+
+ /**
+ * Returns the base type of the simple type or an empty pointer if no base type is
+ * set.
+ */
+ virtual SchemaType::Ptr wxsSuperType() const;
+
+ /**
+ * Sets the context @p component of the simple type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#std-context">Context Definition</a>
+ */
+ void setContext(const NamedSchemaComponent::Ptr &component);
+
+ /**
+ * Returns the context component of the simple type.
+ */
+ NamedSchemaComponent::Ptr context() const;
+
+ /**
+ * Sets the primitive @p type of the simple type.
+ *
+ * The primitive type is only specified if the category is SimpleTypeAtomic.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-primitive">Primitive Type Definition</a>
+ */
+ void setPrimitiveType(const AnySimpleType::Ptr &type);
+
+ /**
+ * Returns the primitive type of the simple type or an empty pointer if the category is
+ * not SimpleTypeAtomic.
+ */
+ AnySimpleType::Ptr primitiveType() const;
+
+ /**
+ * Sets the list item @p type of the simple type.
+ *
+ * The list item type is only specified if the category is SimpleTypeList.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-itemType">Item Type Definition</a>
+ */
+ void setItemType(const AnySimpleType::Ptr &type);
+
+ /**
+ * Returns the list item type of the simple type or an empty pointer if the category is
+ * not SimpleTypeList.
+ */
+ AnySimpleType::Ptr itemType() const;
+
+ /**
+ * Sets the member @p types of the simple type.
+ *
+ * The member types are only specified if the category is SimpleTypeUnion.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-memberTypes">Member Types Definition</a>
+ */
+ void setMemberTypes(const AnySimpleType::List &types);
+
+ /**
+ * Returns the list member types of the simple type or an empty list if the category is
+ * not SimpleTypeUnion.
+ */
+ AnySimpleType::List memberTypes() const;
+
+ /**
+ * Sets the @p facets of the simple type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-facets">Facets Definition</a>
+ */
+ void setFacets(const XsdFacet::Hash &facets);
+
+ /**
+ * Returns the facets of the simple type.
+ */
+ XsdFacet::Hash facets() const;
+
+ /**
+ * Sets the @p category (variety) of the simple type.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#defn-variety">Variety Definition</a>
+ */
+ void setCategory(TypeCategory category);
+
+ /**
+ * Returns the category (variety) of the simple type.
+ */
+ virtual TypeCategory category() const;
+
+ /**
+ * Sets the derivation @p method of the simple type.
+ *
+ * @see DerivationMethod
+ */
+ void setDerivationMethod(DerivationMethod method);
+
+ /**
+ * Returns the derivation method of the simple type.
+ */
+ virtual DerivationMethod derivationMethod() const;
+
+ /**
+ * Always returns @c true.
+ */
+ virtual bool isDefinedBySchema() const;
+
+ private:
+ SchemaType::Ptr m_superType;
+ NamedSchemaComponent::Ptr m_context;
+ AnySimpleType::Ptr m_primitiveType;
+ AnySimpleType::Ptr m_itemType;
+ AnySimpleType::List m_memberTypes;
+ XsdFacet::Hash m_facets;
+ TypeCategory m_typeCategory;
+ DerivationMethod m_derivationMethod;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdstatemachine.cpp b/src/xmlpatterns/schema/qxsdstatemachine.cpp
new file mode 100644
index 0000000..8a43411
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdstatemachine.cpp
@@ -0,0 +1,413 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * NOTE: This file is included by qxsdstatemachine_p.h
+ * if you need some includes, put them in qxsdstatemachine_p.h (outside of the namespace)
+ */
+
+template <typename TransitionType>
+XsdStateMachine<TransitionType>::XsdStateMachine()
+ : m_counter(50)
+{
+}
+
+template <typename TransitionType>
+XsdStateMachine<TransitionType>::XsdStateMachine(const NamePool::Ptr &namePool)
+ : m_namePool(namePool)
+ , m_counter(50)
+{
+}
+
+template <typename TransitionType>
+typename XsdStateMachine<TransitionType>::StateId XsdStateMachine<TransitionType>::addState(StateType type)
+{
+#ifndef QT_NO_DEBUG
+ // make sure we don't have two start states
+ if (type == StartState) {
+ QHashIterator<StateId, StateType> it(m_states);
+ while (it.hasNext()) {
+ it.next();
+ Q_ASSERT(it.value() != StartState && it.value() != StartEndState);
+ }
+ }
+#endif // QT_NO_DEBUG
+
+ // reserve new state id
+ const StateId id = ++m_counter;
+ m_states.insert(id, type);
+
+ // if it is a start state, we make it to our current state
+ if (type == StartState || type == StartEndState)
+ m_currentState = id;
+
+ return id;
+}
+
+template <typename TransitionType>
+void XsdStateMachine<TransitionType>::addTransition(StateId start, TransitionType transition, StateId end)
+{
+ QHash<TransitionType, QVector<StateId> > &hash = m_transitions[start];
+ QVector<StateId> &states = hash[transition];
+ if (!states.contains(end))
+ states.append(end);
+}
+
+template <typename TransitionType>
+void XsdStateMachine<TransitionType>::addEpsilonTransition(StateId start, StateId end)
+{
+ QVector<StateId> &states = m_epsilonTransitions[start];
+ states.append(end);
+}
+
+template <typename TransitionType>
+void XsdStateMachine<TransitionType>::reset()
+{
+ // reset the machine to the start state
+ QHashIterator<StateId, StateType> it(m_states);
+ while (it.hasNext()) {
+ it.next();
+ if (it.value() == StartState || it.value() == StartEndState) {
+ m_currentState = it.key();
+ return;
+ }
+ }
+
+ Q_ASSERT(false);
+}
+
+template <typename TransitionType>
+void XsdStateMachine<TransitionType>::clear()
+{
+ m_states.clear();
+ m_transitions.clear();
+ m_epsilonTransitions.clear();
+ m_currentState = -1;
+ m_counter = 50;
+}
+
+template <typename TransitionType>
+bool XsdStateMachine<TransitionType>::proceed(TransitionType transition)
+{
+ // check that we are not in an invalid state
+ if (!m_transitions.contains(m_currentState)) {
+ return false;
+ }
+
+ // fetch the transition entry for the current state
+ const QHash<TransitionType, QVector<StateId> > &entry = m_transitions[m_currentState];
+ if (entry.contains(transition)) { // is there an transition for the given input?
+ m_currentState = entry.value(transition).first();
+ m_lastTransition = transition;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+template <typename TransitionType>
+QList<TransitionType> XsdStateMachine<TransitionType>::possibleTransitions() const
+{
+ // check that we are not in an invalid state
+ if (!m_transitions.contains(m_currentState)) {
+ return QList<TransitionType>();
+ }
+
+ // fetch the transition entry for the current state
+ const QHash<TransitionType, QVector<StateId> > &entry = m_transitions[m_currentState];
+
+ return entry.keys();
+}
+
+template <typename TransitionType>
+template <typename InputType>
+bool XsdStateMachine<TransitionType>::proceed(InputType input)
+{
+ // check that we are not in an invalid state
+ if (!m_transitions.contains(m_currentState)) {
+ return false;
+ }
+
+ // fetch the transition entry for the current state
+ const QHash<TransitionType, QVector<StateId> > &entry = m_transitions[m_currentState];
+ QHashIterator<TransitionType, QVector<StateId> > it(entry);
+ while (it.hasNext()) {
+ it.next();
+ if (inputEqualsTransition(input, it.key())) {
+ m_currentState = it.value().first();
+ m_lastTransition = it.key();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+template <typename TransitionType>
+template <typename InputType>
+bool XsdStateMachine<TransitionType>::inputEqualsTransition(InputType input, TransitionType transition) const
+{
+ return false;
+}
+
+template <typename TransitionType>
+bool XsdStateMachine<TransitionType>::inEndState() const
+{
+ // check if current state is an end state
+ return (m_states.value(m_currentState) == StartEndState || m_states.value(m_currentState) == EndState);
+}
+
+template <typename TransitionType>
+TransitionType XsdStateMachine<TransitionType>::lastTransition() const
+{
+ return m_lastTransition;
+}
+
+template <typename TransitionType>
+typename XsdStateMachine<TransitionType>::StateId XsdStateMachine<TransitionType>::startState() const
+{
+ QHashIterator<StateId, StateType> it(m_states);
+ while (it.hasNext()) {
+ it.next();
+ if (it.value() == StartState || it.value() == StartEndState)
+ return it.key();
+ }
+
+ Q_ASSERT(false); // should never be reached
+ return -1;
+}
+
+template <typename TransitionType>
+QString XsdStateMachine<TransitionType>::transitionTypeToString(TransitionType type) const
+{
+ Q_UNUSED(type)
+
+ return QString();
+}
+
+template <typename TransitionType>
+bool XsdStateMachine<TransitionType>::outputGraph(QIODevice *device, const QString &graphName) const
+{
+ if (!device->isOpen()) {
+ qWarning("device must be open for writing");
+ return false;
+ }
+
+ QByteArray graph;
+ QTextStream s(&graph);
+
+ QHashIterator<StateId, QHash<TransitionType, QVector<StateId> > > it(m_transitions);
+ QHashIterator<StateId, StateType> it3(m_states);
+
+ s << "digraph " << graphName << " {\n";
+ s << " mindist = 2.0\n";
+
+ // draw edges
+ while (it.hasNext()) {
+ it.next();
+
+ QHashIterator<TransitionType, QVector<StateId> > it2(it.value());
+ while (it2.hasNext()) {
+ it2.next();
+ for (int i = 0; i < it2.value().count(); ++i)
+ s << " " << it.key() << " -> " << it2.value().at(i) << " [label=\"" << transitionTypeToString(it2.key()) << "\"]\n";
+ }
+ }
+
+ QHashIterator<StateId, QVector<StateId> > it4(m_epsilonTransitions);
+ while (it4.hasNext()) {
+ it4.next();
+
+ const QVector<StateId> states = it4.value();
+ for (int i = 0; i < states.count(); ++i)
+ s << " " << it4.key() << " -> " << states.at(i) << " [label=\"&#949;\"]\n";
+ }
+
+ // draw node infos
+ while (it3.hasNext()) {
+ it3.next();
+
+ QString style;
+ if (it3.value() == StartState) {
+ style = QLatin1String("shape=circle, style=filled, color=blue");
+ } else if (it3.value() == StartEndState) {
+ style = QLatin1String("shape=doublecircle, style=filled, color=blue");
+ } else if (it3.value() == InternalState) {
+ style = QLatin1String("shape=circle, style=filled, color=red");
+ } else if (it3.value() == EndState) {
+ style = QLatin1String("shape=doublecircle, style=filled, color=green");
+ }
+
+ s << " " << it3.key() << " [" << style << "]\n";
+ }
+
+ s << "}\n";
+
+ s.flush();
+
+ if (device->write(graph) == -1)
+ return false;
+
+ return true;
+}
+
+
+template <typename TransitionType>
+typename XsdStateMachine<TransitionType>::StateId XsdStateMachine<TransitionType>::dfaStateForNfaState(QSet<StateId> nfaState,
+ QList< QPair<QSet<StateId>, StateId> > &stateTable,
+ XsdStateMachine<TransitionType> &dfa) const
+{
+ // check whether we have the given state in our lookup table
+ // already, in that case simply return it
+ for (int i = 0; i < stateTable.count(); ++i) {
+ if (stateTable.at(i).first == nfaState)
+ return stateTable.at(i).second;
+ }
+
+ // check if the NFA state set contains a Start or End
+ // state, in that case our new DFA state will be a
+ // Start or End state as well
+ StateType type = InternalState;
+ QSetIterator<StateId> it(nfaState);
+ bool hasStartState = false;
+ bool hasEndState = false;
+ while (it.hasNext()) {
+ const StateId state = it.next();
+ if (m_states.value(state) == EndState) {
+ hasEndState = true;
+ } else if (m_states.value(state) == StartState) {
+ hasStartState = true;
+ }
+ }
+ if (hasStartState) {
+ if (hasEndState)
+ type = StartEndState;
+ else
+ type = StartState;
+ } else if (hasEndState) {
+ type = EndState;
+ }
+
+ // create the new DFA state
+ const StateId dfaState = dfa.addState(type);
+
+ // add the new DFA state to the lookup table
+ stateTable.append(qMakePair<QSet<StateId>, StateId>(nfaState, dfaState));
+
+ return dfaState;
+}
+
+template <typename TransitionType>
+XsdStateMachine<TransitionType> XsdStateMachine<TransitionType>::toDFA() const
+{
+ XsdStateMachine<TransitionType> dfa(m_namePool);
+ dfa.m_counter = 100;
+ QList< QPair< QSet<StateId>, StateId> > table;
+ QList< QSet<StateId> > isMarked;
+
+ // search the start state as the algorithm starts with it...
+ StateId startState = -1;
+ QHashIterator<StateId, StateType> stateTypeIt(m_states);
+ while (stateTypeIt.hasNext()) {
+ stateTypeIt.next();
+ if (stateTypeIt.value() == StartState) {
+ startState = stateTypeIt.key();
+ break;
+ }
+ }
+ Q_ASSERT(startState != -1);
+
+ // our list of state set that still have to be processed
+ QList< QSet<StateId> > workStates;
+
+ // add the start state to the list of to processed state sets
+ workStates.append(epsilonClosure(QSet<StateId>() << startState));
+
+ while (!workStates.isEmpty()) { // as long as there are state sets to process left
+
+ // enqueue set of states
+ const QSet<StateId> states = workStates.takeFirst();
+
+ if (isMarked.contains(states)) // we processed this state set already
+ continue;
+
+ // mark as processed
+ isMarked.append(states);
+
+ // select a list of all inputs that are possible for
+ // the 'states' set
+ QList<TransitionType> input;
+
+ {
+ QSetIterator<StateId> it(states);
+ while (it.hasNext()) {
+ input << m_transitions.value(it.next()).keys();
+ }
+ }
+
+ // get the state in DFA that corresponds to the 'states' set in the NFA
+ const StateId dfaBegin = dfaStateForNfaState(states, table, dfa);
+
+ for (int i = 0; i < input.count(); ++i) { // for each possible input
+ // retrieve the states that can be reached from the 'states' set by the
+ // given input or by epsilon transition
+ const QSet<StateId> followStates = epsilonClosure(move(states, input.at(i)));
+
+ // get the state in DFA that corresponds to the 'followStates' set in the NFA
+ const StateId dfaEnd = dfaStateForNfaState(followStates, table, dfa);
+
+ // adds a new transition to the DFA that corresponds to the transitions between
+ // 'states' and 'followStates' in the NFA
+ dfa.addTransition(dfaBegin, input.at(i), dfaEnd);
+
+ // add the 'followStates' to the list of to be processed state sets
+ workStates.append(followStates);
+ }
+ }
+
+ return dfa;
+}
+
+template <typename TransitionType>
+QHash<typename XsdStateMachine<TransitionType>::StateId, typename XsdStateMachine<TransitionType>::StateType> XsdStateMachine<TransitionType>::states() const
+{
+ return m_states;
+}
diff --git a/src/xmlpatterns/schema/qxsdstatemachine_p.h b/src/xmlpatterns/schema/qxsdstatemachine_p.h
new file mode 100644
index 0000000..62c6ab0
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdstatemachine_p.h
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdStateMachine_H
+#define Patternist_XsdStateMachine_H
+
+#include "qnamepool_p.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+#include <QtCore/QTextStream>
+
+class QIODevice;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A state machine used for evaluation.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ template <typename TransitionType>
+ class XsdStateMachine
+ {
+ public:
+ typedef qint32 StateId;
+
+ /**
+ * Describes the type of state.
+ */
+ enum StateType
+ {
+ StartState, ///< The state the machine will start with.
+ StartEndState, ///< The state the machine will start with, can be end state as well.
+ InternalState, ///< Any state that is not start or end state.
+ EndState ///< Any state where the machine is allowed to stop.
+ };
+
+ /**
+ * Creates a new state machine object.
+ */
+ XsdStateMachine();
+
+ /**
+ * Creates a new state machine object.
+ *
+ * The name pool to use for accessing object names.
+ */
+ XsdStateMachine(const NamePool::Ptr &namePool);
+
+ /**
+ * Adds a new state of the given @p type to the state machine.
+ *
+ * @return The id of the new state.
+ */
+ StateId addState(StateType type);
+
+ /**
+ * Adds a new @p transition to the state machine.
+ *
+ * @param start The start state.
+ * @param transition The transition to come from the start to the end state.
+ * @param end The end state.
+ */
+ void addTransition(StateId start, TransitionType transition, StateId end);
+
+ /**
+ * Adds a new epsilon @p transition to the state machine.
+ *
+ * @param start The start state.
+ * @param end The end state.
+ */
+ void addEpsilonTransition(StateId start, StateId end);
+
+ /**
+ * Resets the machine to the start state.
+ */
+ void reset();
+
+ /**
+ * Removes all states and transitions from the state machine.
+ */
+ void clear();
+
+ /**
+ * Continues execution of the machine with the given input @p transition.
+ *
+ * @return @c true if the transition was successful, @c false otherwise.
+ */
+ bool proceed(TransitionType transition);
+
+ /**
+ * Returns the list of transitions that are reachable from the current
+ * state.
+ */
+ QList<TransitionType> possibleTransitions() const;
+
+ /**
+ * Continues execution of the machine with the given @p input.
+ *
+ * @note To use this method, inputEqualsTransition must be implemented
+ * to find the right transition to use.
+ *
+ * @return @c true if the transition was successful, @c false otherwise.
+ */
+ template <typename InputType>
+ bool proceed(InputType input);
+
+ /**
+ * Returns whether the given @p input matches the given @p transition.
+ */
+ template <typename InputType>
+ bool inputEqualsTransition(InputType input, TransitionType transition) const;
+
+ /**
+ * Returns whether the machine is in an allowed end state.
+ */
+ bool inEndState() const;
+
+ /**
+ * Returns the last transition that was taken.
+ */
+ TransitionType lastTransition() const;
+
+ /**
+ * Returns the start state of the machine.
+ */
+ StateId startState() const;
+
+ /**
+ * This method should be redefined by template specialization for every
+ * concret TransitionType.
+ */
+ QString transitionTypeToString(TransitionType type) const;
+
+ /**
+ * Outputs the state machine in DOT format to the given
+ * output @p device.
+ */
+ bool outputGraph(QIODevice *device, const QString &graphName) const;
+
+ /**
+ * Returns a DFA that is equal to the NFA of the state machine.
+ */
+ XsdStateMachine<TransitionType> toDFA() const;
+
+ /**
+ * Returns the information of all states of the state machine.
+ */
+ QHash<StateId, StateType> states() const;
+
+ /**
+ * Returns the information of all transitions of the state machine.
+ *
+ * The implementation is inlined in order to workaround a compiler
+ * bug on Symbian/winscw.
+ */
+ QHash<StateId, QHash<TransitionType, QVector<StateId> > > transitions() const
+ {
+ return m_transitions;
+ }
+
+ private:
+ /**
+ * Returns the DFA state for the given @p nfaStat from the given @p stateTable.
+ * If there is no corresponding DFA state yet, a new one is created.
+ */
+ StateId dfaStateForNfaState(QSet<StateId> nfaState, QList< QPair< QSet<StateId>, StateId> > &stateTable, XsdStateMachine<TransitionType> &dfa) const;
+
+ /**
+ * Returns the set of all states that can be reached from the set of @p input states
+ * by the epsilon transition.
+ *
+ * The implementation is inlined in order to workaround a compiler
+ * bug on Symbian/winscw.
+ */
+ QSet<StateId> epsilonClosure(const QSet<StateId> &input) const
+ {
+ // every state can reach itself by epsilon transition, so include the input states
+ // in the result as well
+ QSet<StateId> result = input;
+
+ // add the input states to the list of to be processed states
+ QList<StateId> workStates = input.toList();
+ while (!workStates.isEmpty()) { // while there are states to be processed left...
+
+ // dequeue one state from list
+ const StateId state = workStates.takeFirst();
+
+ // get the list of states that can be reached by the epsilon transition
+ // from the current 'state'
+ const QVector<StateId> targetStates = m_epsilonTransitions.value(state);
+ for (int i = 0; i < targetStates.count(); ++i) {
+ // if we have this target state not in our result set yet...
+ if (!result.contains(targetStates.at(i))) {
+ // ... add it to the result set
+ result.insert(targetStates.at(i));
+
+ // add the target state to the list of to be processed states as well,
+ // as we want to have the epsilon transitions not only for the first
+ // level of following states
+ workStates.append(targetStates.at(i));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the set of all states that can be reached from the set of given @p states
+ * by the given @p input.
+ *
+ * The implementation is inlined in order to workaround a compiler
+ * bug on Symbian/winscw.
+ */
+ QSet<StateId> move(const QSet<StateId> &states, TransitionType input) const
+ {
+ QSet<StateId> result;
+
+ QSetIterator<StateId> it(states);
+ while (it.hasNext()) { // iterate over all given states
+ const StateId state = it.next();
+
+ // get the transition table for the current state
+ const QHash<TransitionType, QVector<StateId> > transitions = m_transitions.value(state);
+
+ // get the target states for the given input
+ const QVector<StateId> targetStates = transitions.value(input);
+
+ // add all target states to the result
+ for (int i = 0; i < targetStates.size(); ++i)
+ result.insert(targetStates.at(i));
+ }
+
+ return result;
+ }
+
+ NamePool::Ptr m_namePool;
+ QHash<StateId, StateType> m_states;
+ QHash<StateId, QHash<TransitionType, QVector<StateId> > > m_transitions;
+ QHash<StateId, QVector<StateId> > m_epsilonTransitions;
+ StateId m_currentState;
+ qint32 m_counter;
+ TransitionType m_lastTransition;
+ };
+
+ #include "qxsdstatemachine.cpp"
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp
new file mode 100644
index 0000000..fed8a41
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp
@@ -0,0 +1,260 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdstatemachinebuilder_p.h"
+
+#include "qxsdelement_p.h"
+#include "qxsdmodelgroup_p.h"
+#include "qxsdschemahelper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+/*
+ * This methods takes a list of objects and returns a list of list
+ * of all combinations the objects can be ordered.
+ *
+ * e.g. input = [ 1, 2, 3 ]
+ * output = [
+ * [ 1, 2, 3 ],
+ * [ 1, 3, 2 ],
+ * [ 2, 1, 3 ],
+ * [ 2, 3, 1 ],
+ * [ 3, 1, 2 ],
+ * [ 3, 2, 1 ]
+ * ]
+ *
+ * The method is used to create all possible combinations for the particles
+ * in an <all> model group.
+ */
+template <typename T>
+QList< QList<T> > allCombinations(const QList<T> &input)
+{
+ if (input.count() == 1)
+ return (QList< QList<T> >() << input);
+
+ QList< QList<T> > result;
+ for (int i = 0; i < input.count(); ++i) {
+ QList<T> subList = input;
+ T value = subList.takeAt(i);
+
+ QList< QList<T> > subLists = allCombinations(subList);
+ for (int j = 0; j < subLists.count(); ++j) {
+ subLists[j].prepend(value);
+ }
+ result << subLists;
+ }
+
+ return result;
+}
+
+XsdStateMachineBuilder::XsdStateMachineBuilder(XsdStateMachine<XsdTerm::Ptr> *machine, const NamePool::Ptr &namePool, Mode mode)
+ : m_stateMachine(machine), m_namePool(namePool), m_mode(mode)
+{
+}
+
+XsdStateMachine<XsdTerm::Ptr>::StateId XsdStateMachineBuilder::reset()
+{
+ Q_ASSERT(m_stateMachine);
+
+ m_stateMachine->clear();
+
+ return m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::EndState);
+}
+
+XsdStateMachine<XsdTerm::Ptr>::StateId XsdStateMachineBuilder::addStartState(XsdStateMachine<XsdTerm::Ptr>::StateId state)
+{
+ const XsdStateMachine<XsdTerm::Ptr>::StateId startState = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::StartState);
+ m_stateMachine->addEpsilonTransition(startState, state);
+
+ return startState;
+}
+
+/*
+ * Create the FSA according to Algorithm Tp(S) from http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html
+ */
+XsdStateMachine<XsdTerm::Ptr>::StateId XsdStateMachineBuilder::buildParticle(const XsdParticle::Ptr &particle, XsdStateMachine<XsdTerm::Ptr>::StateId endState)
+{
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentStartState = endState;
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentEndState = endState;
+
+ // 2
+ if (particle->maximumOccursUnbounded()) {
+ const XsdStateMachine<XsdTerm::Ptr>::StateId t = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::InternalState);
+ const XsdStateMachine<XsdTerm::Ptr>::StateId n = buildTerm(particle->term(), t);
+
+ m_stateMachine->addEpsilonTransition(t, n);
+ m_stateMachine->addEpsilonTransition(n, endState);
+
+ currentEndState = t;
+ currentStartState = t;
+ } else { // 3
+ int count = (particle->maximumOccurs() - particle->minimumOccurs());
+ if (count > 100)
+ count = 100;
+
+ for (int i = 0; i < count; ++i) {
+ currentStartState = buildTerm(particle->term(), currentEndState);
+ m_stateMachine->addEpsilonTransition(currentStartState, endState);
+ currentEndState = currentStartState;
+ }
+ }
+
+ int minOccurs = particle->minimumOccurs();
+ if (minOccurs > 100)
+ minOccurs = 100;
+
+ for (int i = 0; i < minOccurs; ++i) {
+ currentStartState = buildTerm(particle->term(), currentEndState);
+ currentEndState = currentStartState;
+ }
+
+ return currentStartState;
+}
+
+/*
+ * Create the FSA according to Algorithm Tt(S) from http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html
+ */
+XsdStateMachine<XsdTerm::Ptr>::StateId XsdStateMachineBuilder::buildTerm(const XsdTerm::Ptr &term, XsdStateMachine<XsdTerm::Ptr>::StateId endState)
+{
+ if (term->isWildcard()) { // 1
+ const XsdStateMachine<XsdTerm::Ptr>::StateId b = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::InternalState);
+ m_stateMachine->addTransition(b, term, endState);
+ return b;
+ } else if (term->isElement()) { // 2
+ const XsdStateMachine<XsdTerm::Ptr>::StateId b = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::InternalState);
+ m_stateMachine->addTransition(b, term, endState);
+
+ const XsdElement::Ptr element(term);
+ if (m_mode == CheckingMode) {
+ const XsdElement::List substGroups = element->substitutionGroups();
+ for (int i = 0; i < substGroups.count(); ++i)
+ m_stateMachine->addTransition(b, substGroups.at(i), endState);
+ } else if (m_mode == ValidatingMode) {
+ const XsdElement::List substGroups = element->substitutionGroups();
+ for (int i = 0; i < substGroups.count(); ++i) {
+ if (XsdSchemaHelper::substitutionGroupOkTransitive(element, substGroups.at(i), m_namePool))
+ m_stateMachine->addTransition(b, substGroups.at(i), endState);
+ }
+ }
+
+ return b;
+ } else if (term->isModelGroup()) {
+ const XsdModelGroup::Ptr group(term);
+
+ if (group->compositor() == XsdModelGroup::ChoiceCompositor) { // 3
+ const XsdStateMachine<XsdTerm::Ptr>::StateId b = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::InternalState);
+
+ for (int i = 0; i < group->particles().count(); ++i) {
+ const XsdParticle::Ptr particle(group->particles().at(i));
+ if (particle->maximumOccurs() != 0) {
+ const XsdStateMachine<XsdTerm::Ptr>::StateId state = buildParticle(particle, endState);
+ m_stateMachine->addEpsilonTransition(b, state);
+ }
+ }
+
+ return b;
+ } else if (group->compositor() == XsdModelGroup::SequenceCompositor) { // 4
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentStartState = endState;
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentEndState = endState;
+
+ for (int i = (group->particles().count() - 1); i >= 0; --i) { // iterate reverse
+ const XsdParticle::Ptr particle(group->particles().at(i));
+ if (particle->maximumOccurs() != 0) {
+ currentStartState = buildParticle(particle, currentEndState);
+ currentEndState = currentStartState;
+ }
+ }
+
+ return currentStartState;
+ } else if (group->compositor() == XsdModelGroup::AllCompositor) {
+ const XsdStateMachine<XsdTerm::Ptr>::StateId newStartState = m_stateMachine->addState(XsdStateMachine<XsdTerm::Ptr>::InternalState);
+
+ const QList<XsdParticle::List> list = allCombinations(group->particles());
+
+ for (int i = 0; i < list.count(); ++i) {
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentStartState = endState;
+ XsdStateMachine<XsdTerm::Ptr>::StateId currentEndState = endState;
+
+ const XsdParticle::List particles = list.at(i);
+ for (int j = (particles.count() - 1); j >= 0; --j) { // iterate reverse
+ const XsdParticle::Ptr particle(particles.at(j));
+ if (particle->maximumOccurs() != 0) {
+ currentStartState = buildParticle(particle, currentEndState);
+ currentEndState = currentStartState;
+ }
+ }
+ m_stateMachine->addEpsilonTransition(newStartState, currentStartState);
+ }
+
+ if (list.isEmpty())
+ return endState;
+ else
+ return newStartState;
+ }
+ }
+
+ Q_ASSERT(false);
+ return 0;
+}
+
+static void internalParticleLookupMap(const XsdParticle::Ptr &particle, QHash<XsdTerm::Ptr, XsdParticle::Ptr> &hash)
+{
+ hash.insert(particle->term(), particle);
+
+ if (particle->term()->isModelGroup()) {
+ const XsdModelGroup::Ptr group(particle->term());
+ const XsdParticle::List particles = group->particles();
+ for (int i = 0; i < particles.count(); ++i)
+ internalParticleLookupMap(particles.at(i), hash);
+ }
+}
+
+QHash<XsdTerm::Ptr, XsdParticle::Ptr> XsdStateMachineBuilder::particleLookupMap(const XsdParticle::Ptr &particle)
+{
+ QHash<XsdTerm::Ptr, XsdParticle::Ptr> result;
+ internalParticleLookupMap(particle, result);
+
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h b/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h
new file mode 100644
index 0000000..c17ca9b
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdStateMachineBuilder_H
+#define Patternist_XsdStateMachineBuilder_H
+
+#include "qxsdparticle_p.h"
+#include "qxsdstatemachine_p.h"
+#include "qxsdterm_p.h"
+
+#include <QtCore/QExplicitlySharedDataPointer>
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class to build up validation state machines.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdStateMachineBuilder : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdStateMachineBuilder> Ptr;
+
+ enum Mode
+ {
+ CheckingMode,
+ ValidatingMode
+ };
+
+ /**
+ * Creates a new state machine builder.
+ *
+ * @param machine The state machine it should work on.
+ * @param namePool The name pool used by all schema components.
+ * @param mode The mode the machine shall be build for.
+ */
+ XsdStateMachineBuilder(XsdStateMachine<XsdTerm::Ptr> *machine, const NamePool::Ptr &namePool, Mode mode = CheckingMode);
+
+ /**
+ * Resets the state machine.
+ *
+ * @returns The initial end state.
+ */
+ XsdStateMachine<XsdTerm::Ptr>::StateId reset();
+
+ /**
+ * Prepends a start state to the given @p state.
+ * That is needed to allow the conversion of the state machine from a FSA to a DFA.
+ */
+ XsdStateMachine<XsdTerm::Ptr>::StateId addStartState(XsdStateMachine<XsdTerm::Ptr>::StateId state);
+
+ /**
+ * Creates the state machine for the given @p particle that should have the
+ * given @p endState.
+ *
+ * @returns The new start state.
+ */
+ XsdStateMachine<XsdTerm::Ptr>::StateId buildParticle(const XsdParticle::Ptr &particle, XsdStateMachine<XsdTerm::Ptr>::StateId endState);
+
+ /**
+ * Creates the state machine for the given @p term that should have the
+ * given @p endState.
+ *
+ * @returns The new start state.
+ */
+ XsdStateMachine<XsdTerm::Ptr>::StateId buildTerm(const XsdTerm::Ptr &term, XsdStateMachine<XsdTerm::Ptr>::StateId endState);
+
+ /**
+ * Returns a hash that maps each term that appears inside @p particle, to the particle it belongs.
+ *
+ * @note These information are used by XsdParticleChecker to check particle inheritance.
+ */
+ static QHash<XsdTerm::Ptr, XsdParticle::Ptr> particleLookupMap(const XsdParticle::Ptr &particle);
+
+ private:
+ XsdStateMachine<XsdTerm::Ptr> *m_stateMachine;
+ NamePool::Ptr m_namePool;
+ Mode m_mode;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdterm.cpp b/src/xmlpatterns/schema/qxsdterm.cpp
new file mode 100644
index 0000000..19af613
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdterm.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdterm_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool XsdTerm::isElement() const
+{
+ return false;
+}
+
+bool XsdTerm::isModelGroup() const
+{
+ return false;
+}
+
+bool XsdTerm::isWildcard() const
+{
+ return false;
+}
+
+bool XsdTerm::isReference() const
+{
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdterm_p.h b/src/xmlpatterns/schema/qxsdterm_p.h
new file mode 100644
index 0000000..6b3f66a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdterm_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdTerm_H
+#define Patternist_XsdTerm_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A base class for all particles of a model group.
+ *
+ * This class is the base class for all particles of a model group
+ * as the <em>element</em>, <em>group</em> or <em>any</em> tag, it is not supposed to
+ * be instantiated directly.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSTerm">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdTerm : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdTerm> Ptr;
+
+ /**
+ * Returns @c true if the term is an element, @c false otherwise.
+ */
+ virtual bool isElement() const;
+
+ /**
+ * Returns @c true if the term is a model group (group tag), @c false otherwise.
+ */
+ virtual bool isModelGroup() const;
+
+ /**
+ * Returns @c true if the term is a wildcard (any tag), @c false otherwise.
+ */
+ virtual bool isWildcard() const;
+
+ /**
+ * Returns @c true if the term is a reference, @c false otherwise.
+ *
+ * @note The reference term is only used internally as helper during type resolving.
+ */
+ virtual bool isReference() const;
+
+ protected:
+ /**
+ * This constructor only exists to ensure this class is subclassed.
+ */
+ inline XsdTerm() {};
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdtypechecker.cpp b/src/xmlpatterns/schema/qxsdtypechecker.cpp
new file mode 100644
index 0000000..217932e
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdtypechecker.cpp
@@ -0,0 +1,1339 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdtypechecker_p.h"
+
+#include "qabstractdatetime_p.h"
+#include "qbase64binary_p.h"
+#include "qboolean_p.h"
+#include "qdecimal_p.h"
+#include "qderivedinteger_p.h"
+#include "qduration_p.h"
+#include "qgenericstaticcontext_p.h"
+#include "qhexbinary_p.h"
+#include "qnamespaceresolver_p.h"
+#include "qpatternplatform_p.h"
+#include "qqnamevalue_p.h"
+#include "qvaluefactory_p.h"
+#include "qxmlnamepool.h"
+#include "qxsdschemahelper_p.h"
+#include "qxsdschemamerger_p.h"
+#include "qxsdstatemachine_p.h"
+
+#include "qxsdschemadebugger_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdSchemaSourceLocationReflection::XsdSchemaSourceLocationReflection(const QSourceLocation &location)
+ : m_sourceLocation(location)
+{
+}
+
+const SourceLocationReflection* XsdSchemaSourceLocationReflection::actualReflection() const
+{
+ return this;
+}
+
+QSourceLocation XsdSchemaSourceLocationReflection::sourceLocation() const
+{
+ return m_sourceLocation;
+}
+
+
+static AnySimpleType::Ptr comparableType(const AnySimpleType::Ptr &type)
+{
+ if (!type->isDefinedBySchema()) {
+ return type;
+ } else {
+ const XsdSimpleType::Ptr simpleType(type);
+ if (type->category() == SchemaType::SimpleTypeAtomic) {
+ return simpleType->primitiveType();
+ } else if (type->category() == SchemaType::SimpleTypeList) {
+ return simpleType->itemType();
+ } else if (type->category() == SchemaType::SimpleTypeUnion) {
+ return simpleType->memberTypes().first();
+ }
+ }
+
+ Q_ASSERT(false);
+ return AnySimpleType::Ptr();
+}
+
+static int totalDigitsForSignedLongLong(long long value)
+{
+ QString number = QString::number(value);
+ if (number.startsWith(QLatin1Char('-')))
+ number = number.mid(1);
+
+ return number.length();
+}
+
+static int totalDigitsForUnsignedLongLong(unsigned long long value)
+{
+ const QString number = QString::number(value);
+ return number.length();
+}
+
+static int totalDigitsForDecimal(const QString &lexicalValue)
+{
+ const QLatin1Char zeroChar('0');
+ const int length = lexicalValue.length() - 1;
+
+ // strip leading zeros
+ int pos = 0;
+ while (lexicalValue.at(pos) == zeroChar && (pos != length))
+ pos++;
+
+ QString value = lexicalValue.mid(pos);
+
+ // if contains '.' strip trailing zeros
+ if (value.contains(QLatin1Char('.'))) {
+ pos = value.length() - 1;
+ while (value.at(pos) == zeroChar) {
+ pos--;
+ }
+
+ value = value.left(pos + 1);
+ }
+
+ // check number of digits of remaining string
+ int totalDigits = 0;
+ for (int i = 0; i < value.count(); ++i)
+ if (value.at(i).isDigit())
+ ++totalDigits;
+
+ if (totalDigits == 0)
+ totalDigits = 1;
+
+ return totalDigits;
+}
+
+static int fractionDigitsForDecimal(const QString &lexicalValue)
+{
+ // we use the lexical value here, as the conversion to double might strip
+ // away decimal positions
+
+ QString trimmedValue(lexicalValue.trimmed());
+ const int pos = trimmedValue.indexOf(QLatin1Char('.'));
+ if (pos == -1) // no '.' -> 0 fraction digits
+ return 0;
+ else
+ return (trimmedValue.length() - pos - 1);
+}
+
+XsdTypeChecker::XsdTypeChecker(const XsdSchemaContext::Ptr &context, const QVector<QXmlName> &namespaceBindings, const QSourceLocation &location)
+ : m_context(context)
+ , m_namePool(m_context->namePool())
+ , m_namespaceBindings(namespaceBindings)
+ , m_reflection(new XsdSchemaSourceLocationReflection(location))
+{
+}
+
+XsdTypeChecker::~XsdTypeChecker()
+{
+ delete m_reflection;
+}
+
+QString XsdTypeChecker::normalizedValue(const QString &value, const XsdFacet::Hash &facets)
+{
+ if (!facets.contains(XsdFacet::WhiteSpace))
+ return value;
+
+ const XsdFacet::Ptr whiteSpaceFacet = facets.value(XsdFacet::WhiteSpace);
+
+ const DerivedString<TypeString>::Ptr facetValue = whiteSpaceFacet->value();
+ const QString stringValue = facetValue->stringValue();
+ if (stringValue == XsdSchemaToken::toString(XsdSchemaToken::Preserve))
+ return value;
+ else if (stringValue == XsdSchemaToken::toString(XsdSchemaToken::Replace)) {
+ QString newValue(value);
+ newValue.replace(QLatin1Char('\t'), QLatin1Char(' '));
+ newValue.replace(QLatin1Char('\n'), QLatin1Char(' '));
+ newValue.replace(QLatin1Char('\r'), QLatin1Char(' '));
+
+ return newValue;
+ } else if (stringValue == XsdSchemaToken::toString(XsdSchemaToken::Collapse)) {
+ return value.simplified();
+ }
+
+ return value;
+}
+
+XsdFacet::Hash XsdTypeChecker::mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context)
+{
+ if (!type)
+ return XsdFacet::Hash();
+
+ const XsdFacet::Hash baseFacets = mergedFacetsForType(type->wxsSuperType(), context);
+ const XsdFacet::Hash facets = context->facetsForType(type);
+
+ XsdFacet::Hash result = baseFacets;
+ XsdFacet::HashIterator it(facets);
+ while (it.hasNext()) {
+ it.next();
+
+ result.insert(it.key(), it.value());
+ }
+
+ return result;
+}
+
+bool XsdTypeChecker::isValidString(const QString &normalizedString, const AnySimpleType::Ptr &type, QString &errorMsg, AnySimpleType::Ptr *boundType) const
+{
+ if (type->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) {
+ if (boundType)
+ *boundType = type;
+
+ return true;
+ }
+
+ if (!type->isDefinedBySchema()) {
+ // special QName check
+ if (BuiltinTypes::xsQName->wxsTypeMatches(type)) {
+ if (!XPathHelper::isQName(normalizedString)) {
+ errorMsg = QtXmlPatterns::tr("%1 is not valid according to %2.").arg(formatData(normalizedString)).arg(formatType(m_namePool, type));
+ return false;
+ }
+ }
+
+ const AtomicValue::Ptr value = fromLexical(normalizedString, type, m_context, m_reflection);
+ if (value->hasError()) {
+ errorMsg = QtXmlPatterns::tr("%1 is not valid according to %2.").arg(formatData(normalizedString)).arg(formatType(m_namePool, type));
+ return false;
+ }
+
+ if (!checkConstrainingFacets(value, normalizedString, type, errorMsg)) {
+ return false;
+ }
+
+ if (boundType)
+ *boundType = type;
+
+ } else {
+ const XsdSimpleType::Ptr simpleType(type);
+
+ if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) {
+ AnySimpleType::Ptr targetType = simpleType->primitiveType();
+ if (!simpleType->wxsSuperType()->isDefinedBySchema())
+ targetType = simpleType->wxsSuperType();
+
+ const AtomicValue::Ptr value = fromLexical(normalizedString, targetType, m_context, m_reflection);
+ if (value->hasError()) {
+ errorMsg = QtXmlPatterns::tr("%1 is not valid according to %2.").arg(formatData(normalizedString)).arg(formatType(m_namePool, targetType));
+ return false;
+ }
+
+ if (!checkConstrainingFacets(value, normalizedString, type, errorMsg)) {
+ return false;
+ }
+
+ if (boundType)
+ *boundType = type;
+
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) {
+ QStringList entries = normalizedString.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < entries.count(); ++i) {
+ entries[i] = normalizedValue(entries.at(i), mergedFacetsForType(simpleType->itemType(), m_context));
+ }
+
+ if (!checkConstrainingFacetsList(entries, normalizedString, simpleType->itemType(), mergedFacetsForType(simpleType, m_context), errorMsg)) {
+ return false;
+ }
+
+ for (int i = 0; i < entries.count(); ++i) {
+ if (!isValidString(entries.at(i), simpleType->itemType(), errorMsg)) {
+ return false;
+ }
+ }
+
+ if (boundType)
+ *boundType = simpleType->itemType();
+
+ } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) {
+ if (!checkConstrainingFacetsUnion(normalizedString, normalizedString, simpleType, mergedFacetsForType(simpleType, m_context), errorMsg)) {
+ return false;
+ }
+
+ const AnySimpleType::List memberTypes = simpleType->memberTypes();
+
+ bool foundValidType = false;
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ const XsdFacet::Hash mergedFacets = mergedFacetsForType(memberTypes.at(i), m_context);
+ if (isValidString(normalizedValue(normalizedString, mergedFacets), memberTypes.at(i), errorMsg)) {
+ foundValidType = true;
+
+ if (boundType)
+ *boundType = memberTypes.at(i);
+
+ break;
+ }
+ }
+
+ if (!foundValidType) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::valuesAreEqual(const QString &value, const QString &otherValue, const AnySimpleType::Ptr &type) const
+{
+ const AnySimpleType::Ptr targetType = comparableType(type);
+
+ // if the type is xs:anySimpleType we just do string comparison...
+ if (targetType->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool))
+ return (value == otherValue);
+
+ if (BuiltinTypes::xsQName->wxsTypeMatches(type)) {
+ const QXmlName valueName = convertToQName(value);
+ const QXmlName otherValueName = convertToQName(otherValue);
+
+ if (valueName == otherValueName)
+ return true;
+ }
+
+ if (type->category() == SchemaType::SimpleTypeAtomic) {
+ // ... otherwise we use the casting platform for value comparison
+ const DerivedString<TypeString>::Ptr valueStr = DerivedString<TypeString>::fromLexical(m_namePool, value);
+ const DerivedString<TypeString>::Ptr otherValueStr = DerivedString<TypeString>::fromLexical(m_namePool, otherValue);
+
+ return XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, otherValueStr, targetType, m_context, m_reflection);
+ } else if (type->category() == SchemaType::SimpleTypeList) {
+ const QStringList values = value.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ const QStringList otherValues = otherValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ if (values.count() != otherValues.count())
+ return false;
+
+ for (int i = 0; i < values.count(); ++i) {
+ if (!valuesAreEqual(values.at(i), otherValues.at(i), XsdSimpleType::Ptr(type)->itemType()))
+ return false;
+ }
+
+ return true;
+ } else if (type->category() == SchemaType::SimpleTypeUnion) {
+ const AnySimpleType::List memberTypes = XsdSimpleType::Ptr(type)->memberTypes();
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ if (valuesAreEqual(value, otherValue, memberTypes.at(i))) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ return false;
+}
+
+bool XsdTypeChecker::checkConstrainingFacets(const AtomicValue::Ptr &value, const QString &lexicalValue, const AnySimpleType::Ptr &type, QString &errorMsg) const
+{
+ const XsdFacet::Hash facets = mergedFacetsForType(type, m_context);
+
+ if (BuiltinTypes::xsString->wxsTypeMatches(type) ||
+ BuiltinTypes::xsUntypedAtomic->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsString(value->stringValue(), facets, BuiltinTypes::xsString, errorMsg);
+ } else if (BuiltinTypes::xsAnyURI->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsString(value->stringValue(), facets, BuiltinTypes::xsAnyURI, errorMsg);
+ } else if (BuiltinTypes::xsNOTATION->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsNotation(value->as<QNameValue>()->qName(), facets, errorMsg);
+ } else if (BuiltinTypes::xsUnsignedByte->wxsTypeMatches(type) ||
+ BuiltinTypes::xsUnsignedInt->wxsTypeMatches(type) ||
+ BuiltinTypes::xsUnsignedLong->wxsTypeMatches(type) ||
+ BuiltinTypes::xsUnsignedShort->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsUnsignedInteger(value->as<Numeric>()->toUnsignedInteger(), lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsInteger->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsSignedInteger(value->as<Numeric>()->toInteger(), lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsFloat->wxsTypeMatches(type) ||
+ BuiltinTypes::xsDouble->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDouble(value->as<Numeric>()->toDouble(), lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsDecimal->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDecimal(value, lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsDateTime->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsDateTime, errorMsg);
+ } else if (BuiltinTypes::xsDate->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsDate, errorMsg);
+ } else if (BuiltinTypes::xsGYear->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGYear, errorMsg);
+ } else if (BuiltinTypes::xsGYearMonth->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGYearMonth, errorMsg);
+ } else if (BuiltinTypes::xsGMonth->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGMonth, errorMsg);
+ } else if (BuiltinTypes::xsGMonthDay->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGMonthDay, errorMsg);
+ } else if (BuiltinTypes::xsGDay->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGDay, errorMsg);
+ } else if (BuiltinTypes::xsTime->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDateTime(value->as<AbstractDateTime>()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsTime, errorMsg);
+ } else if (BuiltinTypes::xsDuration->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsDuration(value, lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsBoolean->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsBoolean(value->as<Boolean>()->value(), lexicalValue, facets, errorMsg);
+ } else if (BuiltinTypes::xsHexBinary->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsBinary(value->as<Base64Binary>()->asByteArray(), facets, BuiltinTypes::xsHexBinary, errorMsg);
+ } else if (BuiltinTypes::xsBase64Binary->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsBinary(value->as<Base64Binary>()->asByteArray(), facets, BuiltinTypes::xsBase64Binary, errorMsg);
+ } else if (BuiltinTypes::xsQName->wxsTypeMatches(type)) {
+ return checkConstrainingFacetsQName(value->as<QNameValue>()->qName(), lexicalValue, facets, errorMsg);
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsString(const QString &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Length)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Length);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() != value.length()) {
+ errorMsg = QtXmlPatterns::tr("String content does not match the length facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() > value.length()) {
+ errorMsg = QtXmlPatterns::tr("String content does not match the minLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() < value.length()) {
+ errorMsg = QtXmlPatterns::tr("String content does not match the maxLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(value)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("String content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const DerivedString<TypeString>::Ptr valueStr = DerivedString<TypeString>::fromLexical(m_namePool, value);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), type, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("String content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsSignedInteger(long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection);
+ if (facetValue->toInteger() < value) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match the maxInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection);
+ if (facetValue->toInteger() <= value) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match the maxExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection);
+ if (facetValue->toInteger() > value) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match the minInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection);
+ if (facetValue->toInteger() >= value) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match the minExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const DerivedString<TypeString>::Ptr valueStr = DerivedString<TypeString>::fromLexical(m_namePool, QString::number(value));
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), BuiltinTypes::xsLong, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypePositiveInteger>::Ptr facetValue = facet->value();
+
+ if (totalDigitsForSignedLongLong(value) > facetValue->toInteger()) {
+ errorMsg = QtXmlPatterns::tr("Signed integer content does not match in the totalDigits facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsUnsignedInteger(unsigned long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection);
+ if (facetValue->toUnsignedInteger() < value) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match the maxInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection);
+ if (facetValue->toUnsignedInteger() <= value) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match the maxExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection);
+ if (facetValue->toUnsignedInteger() > value) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match the minInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection);
+ if (facetValue->toUnsignedInteger() >= value) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match the minExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const DerivedString<TypeString>::Ptr valueStr = DerivedString<TypeString>::fromLexical(m_namePool, QString::number(value));
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), BuiltinTypes::xsUnsignedLong, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypePositiveInteger>::Ptr facetValue = facet->value();
+
+ if (totalDigitsForUnsignedLongLong(value) > facetValue->toInteger()) {
+ errorMsg = QtXmlPatterns::tr("Unsigned integer content does not match in the totalDigits facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsDouble(double value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection);
+ if (facetValue->toDouble() < value) {
+ errorMsg = QtXmlPatterns::tr("Double content does not match the maxInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection);
+ if (facetValue->toDouble() <= value) {
+ errorMsg = QtXmlPatterns::tr("Double content does not match the maxExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection);
+ if (facetValue->toDouble() > value) {
+ errorMsg = QtXmlPatterns::tr("Double content does not match the minInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive);
+ const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection);
+ if (facetValue->toDouble() >= value) {
+ errorMsg = QtXmlPatterns::tr("Double content does not match the minExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const DerivedString<TypeString>::Ptr valueStr = DerivedString<TypeString>::fromLexical(m_namePool, QString::number(value));
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), BuiltinTypes::xsDouble, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Double content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Double content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsDecimal(const AtomicValue::Ptr &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::FractionDigits)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::FractionDigits);
+ const DerivedInteger<TypePositiveInteger>::Ptr facetValue = facet->value();
+
+ if (fractionDigitsForDecimal(lexicalValue) > facetValue->toInteger()) {
+ errorMsg = QtXmlPatterns::tr("Decimal content does not match in the fractionDigits facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::TotalDigits)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::TotalDigits);
+ const DerivedInteger<TypePositiveInteger>::Ptr facetValue = facet->value();
+
+ if (totalDigitsForDecimal(lexicalValue) > facetValue->toInteger()) {
+ errorMsg = QtXmlPatterns::tr("Decimal content does not match in the totalDigits facet.");
+ return false;
+ }
+ }
+
+ return checkConstrainingFacetsDouble(value->as<Decimal>()->toDouble(), lexicalValue, facets, errorMsg);
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsDateTime(const QDateTime &value, const QString &lexicalValue, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive);
+ const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ if (facetValue->toDateTime() < value) {
+ errorMsg = QtXmlPatterns::tr("Date time content does not match the maxInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive);
+ const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ if (facetValue->toDateTime() <= value) {
+ errorMsg = QtXmlPatterns::tr("Date time content does not match the maxExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive);
+ const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ if (facetValue->toDateTime() > value) {
+ errorMsg = QtXmlPatterns::tr("Date time content does not match the minInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive);
+ const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ if (facetValue->toDateTime() >= value) {
+ errorMsg = QtXmlPatterns::tr("Date time content does not match the minExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ if (facetValue->toDateTime() == value) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Date time content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Date time content does not match pattern facet.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsDuration(const AtomicValue::Ptr&, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::MaximumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive);
+ const DerivedString<TypeString>::Ptr value = DerivedString<TypeString>::fromLexical(m_namePool, lexicalValue);
+
+ if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MaximumInclusive)->value(), AtomicComparator::OperatorLessThan, value, BuiltinTypes::xsDuration, m_context, m_reflection)) {
+ errorMsg = QtXmlPatterns::tr("Duration content does not match the maxInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive);
+ const DerivedString<TypeString>::Ptr value = DerivedString<TypeString>::fromLexical(m_namePool, lexicalValue);
+
+ if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MaximumExclusive)->value(), AtomicComparator::OperatorLessOrEqual, value, BuiltinTypes::xsDuration, m_context, m_reflection)) {
+ errorMsg = QtXmlPatterns::tr("Duration content does not match the maxExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumInclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive);
+ const DerivedString<TypeString>::Ptr value = DerivedString<TypeString>::fromLexical(m_namePool, lexicalValue);
+
+ if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MinimumInclusive)->value(), AtomicComparator::OperatorGreaterThan, value, BuiltinTypes::xsDuration, m_context, m_reflection)) {
+ errorMsg = QtXmlPatterns::tr("Duration content does not match the minInclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumExclusive)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive);
+ const DerivedString<TypeString>::Ptr value = DerivedString<TypeString>::fromLexical(m_namePool, lexicalValue);
+
+ if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MinimumExclusive)->value(), AtomicComparator::OperatorGreaterOrEqual, value, BuiltinTypes::xsDuration, m_context, m_reflection)) {
+ errorMsg = QtXmlPatterns::tr("Duration content does not match the minExclusive facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const DerivedString<TypeString>::Ptr value = DerivedString<TypeString>::fromLexical(m_namePool, lexicalValue);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(multiValue.at(j), AtomicComparator::OperatorEqual, value, BuiltinTypes::xsDuration, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Duration content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Duration content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsBoolean(bool, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Boolean content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsBinary(const QByteArray &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Length)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Length);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() != value.length()) {
+ errorMsg = QtXmlPatterns::tr("Binary content does not match the length facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() > value.length()) {
+ errorMsg = QtXmlPatterns::tr("Binary content does not match the minLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumLength);
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr length = facet->value();
+ if (length->toInteger() < value.length()) {
+ errorMsg = QtXmlPatterns::tr("Binary content does not match the maxLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const Base64Binary::Ptr binary = ValueFactory::fromLexical(multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue(), type, m_context, m_reflection);
+ const QByteArray facetValue = binary->as<Base64Binary>()->asByteArray();
+ if (value == facetValue) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Binary content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ //TODO: implement
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsQName(const QXmlName &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Length)) {
+ // always true
+ }
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ // always true
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ // always true
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ if (!XPathHelper::isQName(lexicalValue)) {
+ errorMsg = QtXmlPatterns::tr("Invalid QName content: %1.").arg(formatData(lexicalValue));
+ return false;
+ }
+
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QXmlName facetValue = multiValue.at(j)->as<QNameValue>()->qName();
+
+ if (value == facetValue) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("QName content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("QName content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsNotation(const QXmlName &value, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Length)) {
+ // deprecated by spec
+ }
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ // deprecated by spec
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ // deprecated by spec
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QXmlName facetValue = multiValue.at(j)->as<QNameValue>()->qName();
+
+ if (value == facetValue) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Notation content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ //TODO: implement
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsList(const QStringList &values, const QString &lexicalValue, const AnySimpleType::Ptr &itemType, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Length)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr value = facets.value(XsdFacet::Length)->value();
+ if (value->toInteger() != values.count()) {
+ errorMsg = QtXmlPatterns::tr("List content does not match length facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MinimumLength)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr value = facets.value(XsdFacet::MinimumLength)->value();
+ if (value->toInteger() > values.count()) {
+ errorMsg = QtXmlPatterns::tr("List content does not match minLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::MaximumLength)) {
+ const DerivedInteger<TypeNonNegativeInteger>::Ptr value = facets.value(XsdFacet::MaximumLength)->value();
+ if (value->toInteger() < values.count()) {
+ errorMsg = QtXmlPatterns::tr("List content does not match maxLength facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Enumeration)) {
+
+ bool found = false;
+
+ // we have to handle lists with QName derived items differently
+ if (BuiltinTypes::xsQName->wxsTypeMatches(itemType) || BuiltinTypes::xsNOTATION->wxsTypeMatches(itemType)) {
+ // first convert the string values from the instance document to a list of QXmlName
+ QList<QXmlName> instanceValues;
+ for (int i = 0; i < values.count(); ++i) {
+ instanceValues.append(convertToQName(values.at(i)));
+ }
+
+ // fetch the values from the facet and create a list of QXmlNames for each of them
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ for (int i = 0; i < multiValue.count(); ++i) {
+ const QStringList facetValueList = multiValue.at(i)->as<DerivedString<TypeString> >()->stringValue().split(QLatin1Char(' '), QString::SkipEmptyParts);
+
+ // create the list of atomic string values
+ QList<QXmlName> facetValues;
+ for (int j = 0; j < facetValueList.count(); ++j) {
+ facetValues.append(convertToQName(facetValueList.at(j)));
+ }
+
+ // check if both lists have the same length
+ if (instanceValues.count() != facetValues.count())
+ continue;
+
+ // check if both lists are equal, that means the contain equal items in the same order
+ bool matchesAll = true;
+ for (int j = 0; j < instanceValues.count(); ++j) {
+ if (instanceValues.at(j) != facetValues.at(j)) {
+ matchesAll = false;
+ break;
+ }
+ }
+
+ if (matchesAll) {
+ found = true;
+ break;
+ }
+ }
+ } else {
+ // first convert the string values from the instance document to atomic values of type string
+ AtomicValue::List instanceValues;
+ for (int i = 0; i < values.count(); ++i) {
+ instanceValues.append(DerivedString<TypeString>::fromLexical(m_namePool, values.at(i)));
+ }
+
+ // fetch the values from the facet and create a list of atomic string values for each of them
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+
+ const AnySimpleType::Ptr targetType = comparableType(itemType);
+
+ const AtomicValue::List multiValue = facet->multiValue();
+ for (int i = 0; i < multiValue.count(); ++i) {
+ const QStringList facetValueList = multiValue.at(i)->as<DerivedString<TypeString> >()->stringValue().split(QLatin1Char(' '), QString::SkipEmptyParts);
+
+ // create the list of atomic string values
+ AtomicValue::List facetValues;
+ for (int j = 0; j < facetValueList.count(); ++j) {
+ facetValues.append(DerivedString<TypeString>::fromLexical(m_namePool, facetValueList.at(j)));
+ }
+
+ // check if both lists have the same length
+ if (instanceValues.count() != facetValues.count())
+ continue;
+
+ // check if both lists are equal, that means the contain equal items in the same order
+ bool matchesAll = true;
+ for (int j = 0; j < instanceValues.count(); ++j) {
+ if (!XsdSchemaHelper::constructAndCompare(instanceValues.at(j), AtomicComparator::OperatorEqual, facetValues.at(j), targetType, m_context, m_reflection)) {
+ matchesAll = false;
+ break;
+ }
+ }
+
+ if (matchesAll) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("List content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("List content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+bool XsdTypeChecker::checkConstrainingFacetsUnion(const QString &value, const QString &lexicalValue, const XsdSimpleType::Ptr &simpleType, const XsdFacet::Hash &facets, QString &errorMsg) const
+{
+ if (facets.contains(XsdFacet::Enumeration)) {
+ const AnySimpleType::List memberTypes = simpleType->memberTypes();
+
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration);
+
+ // convert the instance value into an atomic string value
+ const DerivedString<TypeString>::Ptr valueString = DerivedString<TypeString>::fromLexical(m_namePool, value);
+
+ // collect the facet values into a list of atomic string values
+ const AtomicValue::List facetValues = facet->multiValue();
+
+ // compare the instance value against the facetValues for each member type and
+ // search for a match
+
+ bool found = false;
+ for (int i = 0; i < memberTypes.count(); ++i) {
+ const AnySimpleType::Ptr targetType = comparableType(memberTypes.at(i));
+ for (int j = 0; j < facetValues.count(); ++j) {
+ if (XsdSchemaHelper::constructAndCompare(valueString, AtomicComparator::OperatorEqual, facetValues.at(j), targetType, m_context, m_reflection)) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Union content is not listed in the enumeration facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Pattern)) {
+ const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern);
+ const AtomicValue::List multiValue = facet->multiValue();
+ bool found = false;
+ for (int j = 0; j < multiValue.count(); ++j) {
+ const QString pattern = multiValue.at(j)->as<DerivedString<TypeString> >()->stringValue();
+ const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection);
+ if (exp.exactMatch(lexicalValue)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ errorMsg = QtXmlPatterns::tr("Union content does not match pattern facet.");
+ return false;
+ }
+ }
+ if (facets.contains(XsdFacet::Assertion)) {
+ //TODO: implement
+ }
+
+ return true;
+}
+
+AtomicValue::Ptr XsdTypeChecker::fromLexical(const QString &value, const SchemaType::Ptr &type, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const
+{
+ if (type->name(m_namePool) == BuiltinTypes::xsNOTATION->name(m_namePool) || type->name(m_namePool) == BuiltinTypes::xsQName->name(m_namePool)) {
+ if (value.simplified().isEmpty())
+ return ValidationError::createError(QtXmlPatterns::tr("Data of type %1 are not allowed to be empty.").arg(formatType(m_namePool, BuiltinTypes::xsNOTATION)));
+
+ const QXmlName valueName = convertToQName(value);
+ return QNameValue::fromValue(m_namePool, valueName);
+ } else {
+ return ValueFactory::fromLexical(value, type, context, reflection);
+ }
+}
+
+QXmlName XsdTypeChecker::convertToQName(const QString &name) const
+{
+ const int pos = name.indexOf(QLatin1Char(':'));
+
+ QXmlName::PrefixCode prefixCode = 0;
+ QXmlName::NamespaceCode namespaceCode;
+ QXmlName::LocalNameCode localNameCode;
+ if (pos != -1) {
+ prefixCode = m_context->namePool()->allocatePrefix(name.left(pos));
+ namespaceCode = StandardNamespaces::empty;
+ for (int i = 0; i < m_namespaceBindings.count(); ++i) {
+ if (m_namespaceBindings.at(i).prefix() == prefixCode) {
+ namespaceCode = m_namespaceBindings.at(i).namespaceURI();
+ break;
+ }
+ }
+ localNameCode = m_context->namePool()->allocateLocalName(name.mid(pos + 1));
+ } else {
+ prefixCode = StandardPrefixes::empty;
+ namespaceCode = StandardNamespaces::empty;
+ for (int i = 0; i < m_namespaceBindings.count(); ++i) {
+ if (m_namespaceBindings.at(i).prefix() == prefixCode) {
+ namespaceCode = m_namespaceBindings.at(i).namespaceURI();
+ break;
+ }
+ }
+ localNameCode = m_context->namePool()->allocateLocalName(name);
+ }
+
+ return QXmlName(namespaceCode, localNameCode, prefixCode);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdtypechecker_p.h b/src/xmlpatterns/schema/qxsdtypechecker_p.h
new file mode 100644
index 0000000..ae90bdc
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdtypechecker_p.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdTypeChecker_H
+#define Patternist_XsdTypeChecker_H
+
+#include <QtXmlPatterns/QSourceLocation>
+
+#include "qschematype_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qxsdschemacontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlQuery;
+
+namespace QPatternist
+{
+ /**
+ * @short An implementation of SourceLocationReflection that takes a QSourceLocation.
+ *
+ * This is a convenience class which provides a QSourceLocation with a SourceLocationReflection
+ * interface.
+ */
+ class XsdSchemaSourceLocationReflection : public SourceLocationReflection
+ {
+ public:
+ XsdSchemaSourceLocationReflection(const QSourceLocation &location);
+
+ virtual const SourceLocationReflection *actualReflection() const;
+ virtual QSourceLocation sourceLocation() const;
+
+ private:
+ const QSourceLocation m_sourceLocation;
+ };
+
+ /**
+ * @short The class that provides methods for checking a string against a type.
+ *
+ * The class provides functionality for type-aware string handling.
+ */
+ class XsdTypeChecker
+ {
+ public:
+ /**
+ * Creates a new type checker.
+ *
+ * @param context The schema context that is used for error reporting.
+ * @param namespaceBindings The namespace bindings that shall be used to check against xs:QName based types.
+ * @param location The source location that is used for error reporting.
+ */
+ XsdTypeChecker(const XsdSchemaContext::Ptr &context, const QVector<QXmlName> &namespaceBindings, const QSourceLocation &location);
+
+ /**
+ * Destroys the type checker.
+ */
+ ~XsdTypeChecker();
+
+ /**
+ * Returns all facets for the given @p type.
+ *
+ * The list of facets is created by following the type hierarchy from xs:anyType down to the given type
+ * and merging the facets in each step.
+ */
+ static XsdFacet::Hash mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context);
+
+ /**
+ * Returns the normalized value for the given @p value.
+ *
+ * The normalized value is the original value with all the white space facets
+ * applied on it.
+ *
+ * @param value The original value.
+ * @param facets The hash of all facets of the values type.
+ */
+ static QString normalizedValue(const QString &value, const XsdFacet::Hash &facets);
+
+ /**
+ * Checks whether the @p normalizedString is valid according the given @p type.
+ *
+ * @param normalizedString The string in normalized form (whitespace facets applied).
+ * @param type The type the string shall be tested against.
+ * @param errorMsg Contains the error message if the normalizedString does not match the type.
+ * @param boundType The type the data was bound to during validation.
+ *
+ * @note The @p boundType only differs from @p type if the type is derived from an based union value.
+ */
+ bool isValidString(const QString &normalizedString, const AnySimpleType::Ptr &type, QString &errorMsg, AnySimpleType::Ptr *boundType = 0) const;
+
+ /**
+ * Returns whether the given @p value and @p otherValue are of @p type and are equal.
+ */
+ bool valuesAreEqual(const QString &value, const QString &otherValue, const AnySimpleType::Ptr &type) const;
+
+ private:
+ Q_DISABLE_COPY(XsdTypeChecker)
+
+ /**
+ * Checks the given value against the facets of @p type.
+ */
+ bool checkConstrainingFacets(const AtomicValue::Ptr &value, const QString &lexicalValue, const AnySimpleType::Ptr &type, QString &errorMsg) const;
+ bool checkConstrainingFacetsString(const QString &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const;
+ bool checkConstrainingFacetsSignedInteger(long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsUnsignedInteger(unsigned long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsDouble(double value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsDecimal(const AtomicValue::Ptr &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsDateTime(const QDateTime &value, const QString &lexicalValue, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const;
+ bool checkConstrainingFacetsDuration(const AtomicValue::Ptr &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsBoolean(bool value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsBinary(const QByteArray &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const;
+ bool checkConstrainingFacetsQName(const QXmlName&, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsNotation(const QXmlName &value, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsList(const QStringList &values, const QString &lexicalValue, const AnySimpleType::Ptr &itemType, const XsdFacet::Hash &facets, QString &errorMsg) const;
+ bool checkConstrainingFacetsUnion(const QString &value, const QString &lexicalValue, const XsdSimpleType::Ptr &simpleType, const XsdFacet::Hash &facets, QString &errorMsg) const;
+
+ /**
+ * Creates an atomic value of @p type from the given string @p value.
+ */
+ AtomicValue::Ptr fromLexical(const QString &value, const SchemaType::Ptr &type, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const;
+
+ /**
+ * Converts a qualified name into a QXmlName according to the namespace
+ * mappings of the current node.
+ */
+ QXmlName convertToQName(const QString &name) const;
+
+ XsdSchemaContext::Ptr m_context;
+ XsdSchema::Ptr m_schema;
+ const NamePool::Ptr m_namePool;
+ QVector<QXmlName> m_namespaceBindings;
+ SourceLocationReflection* m_reflection;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsduserschematype.cpp b/src/xmlpatterns/schema/qxsduserschematype.cpp
new file mode 100644
index 0000000..95892e1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsduserschematype.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * NOTE: This file is included by qxsduserschematype_p.h
+ * if you need some includes, put them in qxsduserschematype_p.h (outside of the namespace)
+ */
+
+template<typename TSuperClass>
+void XsdUserSchemaType<TSuperClass>::setName(const QXmlName &name)
+{
+ m_name = name;
+}
+
+template<typename TSuperClass>
+QXmlName XsdUserSchemaType<TSuperClass>::name(const NamePool::Ptr&) const
+{
+ return m_name;
+}
+
+template<typename TSuperClass>
+QString XsdUserSchemaType<TSuperClass>::displayName(const NamePool::Ptr &np) const
+{
+ return np->displayName(m_name);
+}
+
+template<typename TSuperClass>
+void XsdUserSchemaType<TSuperClass>::setDerivationConstraints(const SchemaType::DerivationConstraints &constraints)
+{
+ m_derivationConstraints = constraints;
+}
+
+template<typename TSuperClass>
+SchemaType::DerivationConstraints XsdUserSchemaType<TSuperClass>::derivationConstraints() const
+{
+ return m_derivationConstraints;
+}
diff --git a/src/xmlpatterns/schema/qxsduserschematype_p.h b/src/xmlpatterns/schema/qxsduserschematype_p.h
new file mode 100644
index 0000000..72162d5
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsduserschematype_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdUserSchemaType_H
+#define Patternist_XsdUserSchemaType_H
+
+#include "qnamedschemacomponent_p.h"
+#include "qschematype_p.h"
+#include "qxsdannotated_p.h"
+
+template<typename N, typename M> class QHash;
+template<typename N> class QList;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A base class for all user defined simple and complex types.
+ *
+ * This class was introduced to combine the SchemaType class and the
+ * NamedSchemaComponent class without explicit inheritance.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ template<typename TSuperClass>
+ class XsdUserSchemaType : public TSuperClass, public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdUserSchemaType> Ptr;
+
+ /**
+ * Sets the @p name of the type.
+ */
+ void setName(const QXmlName &name);
+
+ /**
+ * Returns the name of the type.
+ *
+ * @param namePool The pool the name belongs to.
+ */
+ virtual QXmlName name(const NamePool::Ptr &namePool) const;
+
+ /**
+ * Returns the display name of the type.
+ *
+ * @param namePool The pool the name belongs to.
+ */
+ virtual QString displayName(const NamePool::Ptr &namePool) const;
+
+ /**
+ * Sets the derivation @p constraints of the type.
+ */
+ void setDerivationConstraints(const SchemaType::DerivationConstraints &constraints);
+
+ /**
+ * Returns the derivation constraints of the type.
+ */
+ SchemaType::DerivationConstraints derivationConstraints() const;
+
+ private:
+ QXmlName m_name;
+ SchemaType::DerivationConstraints m_derivationConstraints;
+ };
+
+ #include "qxsduserschematype.cpp"
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp
new file mode 100644
index 0000000..3cbb6c1
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdvalidatedxmlnodemodel_p.h"
+
+#include <QtCore/QUrl>
+#include <QtCore/QVariant>
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XsdValidatedXmlNodeModel::XsdValidatedXmlNodeModel(const QAbstractXmlNodeModel *model)
+ : m_internalModel(model)
+{
+}
+
+XsdValidatedXmlNodeModel::~XsdValidatedXmlNodeModel()
+{
+}
+
+QUrl XsdValidatedXmlNodeModel::baseUri(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->baseUri(index);
+}
+
+QUrl XsdValidatedXmlNodeModel::documentUri(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->documentUri(index);
+}
+
+QXmlNodeModelIndex::NodeKind XsdValidatedXmlNodeModel::kind(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->kind(index);
+}
+
+QXmlNodeModelIndex::DocumentOrder XsdValidatedXmlNodeModel::compareOrder(const QXmlNodeModelIndex &index, const QXmlNodeModelIndex &otherIndex) const
+{
+ return m_internalModel->compareOrder(index, otherIndex);
+}
+
+QXmlNodeModelIndex XsdValidatedXmlNodeModel::root(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->root(index);
+}
+
+QXmlName XsdValidatedXmlNodeModel::name(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->name(index);
+}
+
+QString XsdValidatedXmlNodeModel::stringValue(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->stringValue(index);
+}
+
+QVariant XsdValidatedXmlNodeModel::typedValue(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->typedValue(index);
+}
+
+QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > XsdValidatedXmlNodeModel::iterate(const QXmlNodeModelIndex &index, QXmlNodeModelIndex::Axis axis) const
+{
+ return m_internalModel->iterate(index, axis);
+}
+
+QPatternist::ItemIteratorPtr XsdValidatedXmlNodeModel::sequencedTypedValue(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->sequencedTypedValue(index);
+}
+
+QPatternist::ItemTypePtr XsdValidatedXmlNodeModel::type(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->type(index);
+}
+
+QXmlName::NamespaceCode XsdValidatedXmlNodeModel::namespaceForPrefix(const QXmlNodeModelIndex &index, const QXmlName::PrefixCode prefix) const
+{
+ return m_internalModel->namespaceForPrefix(index, prefix);
+}
+
+bool XsdValidatedXmlNodeModel::isDeepEqual(const QXmlNodeModelIndex &index, const QXmlNodeModelIndex &otherIndex) const
+{
+ return m_internalModel->isDeepEqual(index, otherIndex);
+}
+
+void XsdValidatedXmlNodeModel::sendNamespaces(const QXmlNodeModelIndex &index, QAbstractXmlReceiver *const receiver) const
+{
+ m_internalModel->sendNamespaces(index, receiver);
+}
+
+QVector<QXmlName> XsdValidatedXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->namespaceBindings(index);
+}
+
+QXmlNodeModelIndex XsdValidatedXmlNodeModel::elementById(const QXmlName &name) const
+{
+ return m_internalModel->elementById(name);
+}
+
+QVector<QXmlNodeModelIndex> XsdValidatedXmlNodeModel::nodesByIdref(const QXmlName &name) const
+{
+ return m_internalModel->nodesByIdref(name);
+}
+
+void XsdValidatedXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &index, QAbstractXmlReceiver *const receiver, const NodeCopySettings &settings) const
+{
+ return m_internalModel->copyNodeTo(index, receiver, settings);
+}
+
+QXmlNodeModelIndex XsdValidatedXmlNodeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
+{
+ return m_internalModel->nextFromSimpleAxis(axis, origin);
+}
+
+QVector<QXmlNodeModelIndex> XsdValidatedXmlNodeModel::attributes(const QXmlNodeModelIndex &index) const
+{
+ return m_internalModel->attributes(index);
+}
+
+void XsdValidatedXmlNodeModel::setAssignedElement(const QXmlNodeModelIndex &index, const XsdElement::Ptr &element)
+{
+ m_assignedElements.insert(index, element);
+}
+
+XsdElement::Ptr XsdValidatedXmlNodeModel::assignedElement(const QXmlNodeModelIndex &index) const
+{
+ if (m_assignedElements.contains(index))
+ return m_assignedElements.value(index);
+ else
+ return XsdElement::Ptr();
+}
+
+void XsdValidatedXmlNodeModel::setAssignedAttribute(const QXmlNodeModelIndex &index, const XsdAttribute::Ptr &attribute)
+{
+ m_assignedAttributes.insert(index, attribute);
+}
+
+XsdAttribute::Ptr XsdValidatedXmlNodeModel::assignedAttribute(const QXmlNodeModelIndex &index) const
+{
+ if (m_assignedAttributes.contains(index))
+ return m_assignedAttributes.value(index);
+ else
+ return XsdAttribute::Ptr();
+}
+
+void XsdValidatedXmlNodeModel::setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type)
+{
+ m_assignedTypes.insert(index, type);
+}
+
+SchemaType::Ptr XsdValidatedXmlNodeModel::assignedType(const QXmlNodeModelIndex &index) const
+{
+ if (m_assignedTypes.contains(index))
+ return m_assignedTypes.value(index);
+ else
+ return SchemaType::Ptr();
+}
+
+void XsdValidatedXmlNodeModel::addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding)
+{
+ m_idIdRefBindings[id].insert(binding);
+}
+
+QStringList XsdValidatedXmlNodeModel::idIdRefBindingIds() const
+{
+ return m_idIdRefBindings.keys();
+}
+
+QSet<NamedSchemaComponent::Ptr> XsdValidatedXmlNodeModel::idIdRefBindings(const QString &id) const
+{
+ return m_idIdRefBindings.value(id);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h
new file mode 100644
index 0000000..c502835
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdValidatedXmlNodeModel_H
+#define Patternist_XsdValidatedXmlNodeModel_H
+
+#include "qabstractxmlnodemodel.h"
+
+#include "qabstractxmlforwarditerator_p.h"
+#include "qitem_p.h"
+#include "qschematype_p.h"
+#include "qxsdelement_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A delegate class that wraps around a QAbstractXmlNodeModel and provides
+ * additional validation specific information.
+ *
+ * This class represents the input XML document enriched with additional type
+ * information that has been assigned during validation.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdValidatedXmlNodeModel : public QAbstractXmlNodeModel
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdValidatedXmlNodeModel> Ptr;
+ typedef QList<Ptr> List;
+
+ /**
+ * Creates a new validated xml node model.
+ */
+ XsdValidatedXmlNodeModel(const QAbstractXmlNodeModel *model);
+
+ /**
+ * Destroys the validated xml node model.
+ */
+ virtual ~XsdValidatedXmlNodeModel();
+
+ virtual QUrl baseUri(const QXmlNodeModelIndex &ni) const;
+ virtual QUrl documentUri(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const;
+ virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex &n) const;
+ virtual QXmlName name(const QXmlNodeModelIndex &ni) const;
+ virtual QString stringValue(const QXmlNodeModelIndex &n) const;
+ virtual QVariant typedValue(const QXmlNodeModelIndex &n) const;
+ virtual QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > iterate(const QXmlNodeModelIndex &ni, QXmlNodeModelIndex::Axis axis) const;
+ virtual QPatternist::ItemIteratorPtr sequencedTypedValue(const QXmlNodeModelIndex &ni) const;
+ virtual QPatternist::ItemTypePtr type(const QXmlNodeModelIndex &ni) const;
+ virtual QXmlName::NamespaceCode namespaceForPrefix(const QXmlNodeModelIndex &ni, const QXmlName::PrefixCode prefix) const;
+ virtual bool isDeepEqual(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const;
+ virtual void sendNamespaces(const QXmlNodeModelIndex &n, QAbstractXmlReceiver *const receiver) const;
+ virtual QVector<QXmlName> namespaceBindings(const QXmlNodeModelIndex &n) const;
+ virtual QXmlNodeModelIndex elementById(const QXmlName &NCName) const;
+ virtual QVector<QXmlNodeModelIndex> nodesByIdref(const QXmlName &NCName) const;
+ virtual void copyNodeTo(const QXmlNodeModelIndex &node, QAbstractXmlReceiver *const receiver, const NodeCopySettings &) const;
+
+ /**
+ * Sets the @p element that is assigned to the xml node at @p index.
+ */
+ void setAssignedElement(const QXmlNodeModelIndex &index, const XsdElement::Ptr &element);
+
+ /**
+ * Returns the element that is assigned to the xml node at @p index.
+ */
+ XsdElement::Ptr assignedElement(const QXmlNodeModelIndex &index) const;
+
+ /**
+ * Sets the @p attribute that is assigned to the xml node at @p index.
+ */
+ void setAssignedAttribute(const QXmlNodeModelIndex &index, const XsdAttribute::Ptr &attribute);
+
+ /**
+ * Returns the attribute that is assigned to the xml node at @p index.
+ */
+ XsdAttribute::Ptr assignedAttribute(const QXmlNodeModelIndex &index) const;
+
+ /**
+ * Sets the @p type that is assigned to the xml node at @p index.
+ *
+ * @note The type can be a different than the type of the element or
+ * attribute that is assigned to the index, since the instance
+ * document can overwrite it by xsi:type.
+ */
+ void setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type);
+
+ /**
+ * Returns the type that is assigned to the xml node at @p index.
+ */
+ SchemaType::Ptr assignedType(const QXmlNodeModelIndex &index) const;
+
+ /**
+ * Adds the attribute or element @p binding with the given @p id.
+ */
+ void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding);
+
+ /**
+ * Returns a list of all binding ids.
+ */
+ QStringList idIdRefBindingIds() const;
+
+ /**
+ * Returns the set of bindings with the given @p id.
+ */
+ QSet<NamedSchemaComponent::Ptr> idIdRefBindings(const QString &id) const;
+
+ protected:
+ virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const;
+ virtual QVector<QXmlNodeModelIndex> attributes(const QXmlNodeModelIndex &element) const;
+
+ private:
+ QExplicitlySharedDataPointer<const QAbstractXmlNodeModel> m_internalModel;
+ QHash<QXmlNodeModelIndex, XsdElement::Ptr> m_assignedElements;
+ QHash<QXmlNodeModelIndex, XsdAttribute::Ptr> m_assignedAttributes;
+ QHash<QXmlNodeModelIndex, SchemaType::Ptr> m_assignedTypes;
+ QHash<QString, QSet<NamedSchemaComponent::Ptr> > m_idIdRefBindings;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp
new file mode 100644
index 0000000..622a39f
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp
@@ -0,0 +1,1276 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdvalidatinginstancereader_p.h"
+
+#include "qabstractdatetime_p.h"
+#include "qacceltreeresourceloader_p.h"
+#include "qbase64binary_p.h"
+#include "qboolean_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qderivedinteger_p.h"
+#include "qduration_p.h"
+#include "qgenericstaticcontext_p.h"
+#include "qhexbinary_p.h"
+#include "qnamespaceresolver_p.h"
+#include "qpatternplatform_p.h"
+#include "qqnamevalue_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qvaluefactory_p.h"
+#include "qxmlnamepool.h"
+#include "qxmlquery_p.h"
+#include "qxmlschema_p.h"
+#include "qxsdschemahelper_p.h"
+#include "qxsdschemamerger_p.h"
+#include "qxsdstatemachine_p.h"
+#include "qxsdstatemachinebuilder_p.h"
+#include "qxsdtypechecker_p.h"
+
+#include "qxsdschemadebugger_p.h"
+
+#include <QtCore/QFile>
+#include <QtXmlPatterns/QXmlQuery>
+#include <QtXmlPatterns/QXmlResultItems>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+ template <>
+ template <>
+ bool XsdStateMachine<XsdTerm::Ptr>::inputEqualsTransition<QXmlName>(QXmlName name, XsdTerm::Ptr term) const
+ {
+ if (term->isElement()) {
+ return (XsdElement::Ptr(term)->name(m_namePool) == name);
+ } else if (term->isWildcard()) {
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ if (name.namespaceURI() == StandardNamespaces::empty) {
+ name.setNamespaceURI(m_namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+ }
+
+ return XsdSchemaHelper::wildcardAllowsExpandedName(name, XsdWildcard::Ptr(term), m_namePool);
+ }
+
+ return false;
+ }
+}
+
+XsdValidatingInstanceReader::XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context)
+ : XsdInstanceReader(model, context)
+ , m_model(model)
+ , m_namePool(m_context->namePool())
+ , m_xsiNilName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("nil")))
+ , m_xsiTypeName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("type")))
+ , m_xsiSchemaLocationName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("schemaLocation")))
+ , m_xsiNoNamespaceSchemaLocationName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("noNamespaceSchemaLocation")))
+ , m_documentUri(documentUri)
+{
+ m_idRefsType = m_context->schemaTypeFactory()->createSchemaType(m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("IDREFS")));
+}
+
+void XsdValidatingInstanceReader::addSchema(const XsdSchema::Ptr &schema, const QUrl &locationUrl)
+{
+ if (!m_mergedSchemas.contains(locationUrl)) {
+ m_mergedSchemas.insert(locationUrl, QStringList() << schema->targetNamespace());
+ } else {
+ QStringList &targetNamespaces = m_mergedSchemas[locationUrl];
+ if (targetNamespaces.contains(schema->targetNamespace()))
+ return;
+
+ targetNamespaces.append(schema->targetNamespace());
+ }
+
+ const XsdSchemaMerger merger(m_schema, schema);
+ m_schema = merger.mergedSchema();
+/*
+ XsdSchemaDebugger dbg(m_namePool);
+ dbg.dumpSchema(m_schema);
+*/
+}
+
+bool XsdValidatingInstanceReader::read()
+{
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ return true;
+
+ if (isStartElement()) {
+ const QXmlName elementName = name();
+ const QXmlItem currentItem = item();
+ bool hasStateMachine = false;
+ XsdElement::Ptr processedElement;
+
+ if (!validate(hasStateMachine, processedElement))
+ return false;
+
+ read();
+
+ if (processedElement) { // for wildcard with 'skip' we have no element
+ m_model->setAssignedElement(currentItem.toNodeModelIndex(), processedElement);
+
+ // check identity constraints after all child nodes have been
+ // validated, so that we know there assigned types
+ validateIdentityConstraint(processedElement, currentItem);
+ }
+
+ if (!m_stateMachines.isEmpty() && hasStateMachine) {
+ if (!m_stateMachines.top().inEndState()) {
+ error(QtXmlPatterns::tr("Element %1 is missing child element.").arg(formatKeyword(m_namePool->displayName(elementName))));
+ return false;
+ }
+ m_stateMachines.pop();
+ }
+ }
+ }
+
+ // final validations
+
+ // check IDREF occurrences
+ const QStringList ids = m_model->idIdRefBindingIds();
+ QSetIterator<QString> it(m_idRefs);
+ while (it.hasNext()) {
+ const QString id = it.next();
+ if (!ids.contains(id)) {
+ error(QtXmlPatterns::tr("There is one IDREF value with no corresponding ID: %1.").arg(formatKeyword(id)));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void XsdValidatingInstanceReader::error(const QString &msg) const
+{
+ m_context.data()->error(msg, XsdSchemaContext::XSDError, sourceLocation());
+}
+
+bool XsdValidatingInstanceReader::loadSchema(const QString &targetNamespace, const QUrl &location)
+{
+ const AutoPtr<QNetworkReply> reply(AccelTreeResourceLoader::load(location, m_context->networkAccessManager(),
+ m_context, AccelTreeResourceLoader::ContinueOnError));
+ if (!reply)
+ return true;
+
+ // we have to create a separated schema context here, that however shares the type factory
+ XsdSchemaContext::Ptr context(new XsdSchemaContext(m_namePool));
+ context->m_schemaTypeFactory = m_context->m_schemaTypeFactory;
+
+ QXmlSchemaPrivate schema(context);
+ schema.load(reply.data(), location, targetNamespace);
+ if (!schema.isValid()) {
+ error(QtXmlPatterns::tr("Loaded schema file is invalid."));
+ return false;
+ }
+
+ addSchema(schema.m_schemaParserContext->schema(), location);
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validate(bool &hasStateMachine, XsdElement::Ptr &processedElement)
+{
+ // first check if a custom schema is defined
+ if (hasAttribute(m_xsiSchemaLocationName)) {
+ const QString schemaLocation = attribute(m_xsiSchemaLocationName);
+ const QStringList parts = schemaLocation.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ if ((parts.count()%2) == 1) {
+ error(QtXmlPatterns::tr("%1 contains invalid data.").arg(formatKeyword(m_namePool, m_xsiSchemaLocationName)));
+ return false;
+ }
+
+ for (int i = 0; i < parts.count(); i += 2) {
+ const QString identifier = QString::fromLatin1("%1 %2").arg(parts.at(i)).arg(parts.at(i + 1));
+ if (m_processedSchemaLocations.contains(identifier))
+ continue;
+ else
+ m_processedSchemaLocations.insert(identifier);
+
+ // check constraint 4) from http://www.w3.org/TR/xmlschema-1/#schema-loc (only valid for XML Schema 1.0?)
+ if (m_processedNamespaces.contains(parts.at(i))) {
+ error(QtXmlPatterns::tr("xsi:schemaLocation namespace %1 has already appeared earlier in the instance document.").arg(formatKeyword(parts.at(i))));
+ return false;
+ }
+
+ QUrl url(parts.at(i + 1));
+ if (url.isRelative()) {
+ Q_ASSERT(m_documentUri.isValid());
+
+ url = m_documentUri.resolved(url);
+ }
+
+ loadSchema(parts.at(i), url);
+ }
+ }
+
+ if (hasAttribute(m_xsiNoNamespaceSchemaLocationName)) {
+ const QString schemaLocation = attribute(m_xsiNoNamespaceSchemaLocationName);
+
+ if (!m_processedSchemaLocations.contains(schemaLocation)) {
+ m_processedSchemaLocations.insert(schemaLocation);
+
+ if (m_processedNamespaces.contains(QString())) {
+ error(QtXmlPatterns::tr("xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute."));
+ return false;
+ }
+
+ QUrl url(schemaLocation);
+ if (url.isRelative()) {
+ Q_ASSERT(m_documentUri.isValid());
+
+ url = m_documentUri.resolved(url);
+ }
+
+ loadSchema(QString(), url);
+ }
+ }
+
+ m_processedNamespaces.insert(m_namePool->stringForNamespace(name().namespaceURI()));
+
+ if (!m_schema) {
+ error(QtXmlPatterns::tr("No schema defined for validation."));
+ return false;
+ }
+
+ // check if we are 'inside' a type definition
+ if (m_stateMachines.isEmpty()) {
+ // find out the type of the top-level element
+ XsdElement::Ptr element = elementByName(name());
+ if (!element) {
+ if (!hasAttribute(m_xsiTypeName)) {
+ error(QtXmlPatterns::tr("No definition for element %1 available.").arg(formatKeyword(m_namePool, name())));
+ return false;
+ }
+
+ // This instance document has an element with no definition in the schema
+ // but an explicitly given type, that is fine according to the spec.
+ // We will create an element definition manually here and continue the
+ // normal validation process
+ element = XsdElement::Ptr(new XsdElement());
+ element->setName(name());
+ element->setIsAbstract(false);
+ element->setIsNillable(hasAttribute(m_xsiNilName));
+
+ const QString type = qNameAttribute(m_xsiTypeName);
+ const QXmlName typeName = convertToQName(type);
+
+ const SchemaType::Ptr elementType = typeByName(typeName);
+ if (!elementType) {
+ error(QtXmlPatterns::tr("Specified type %1 is not known to the schema.").arg(formatType(m_namePool, typeName)));
+ return false;
+ }
+ element->setType(elementType);
+ }
+
+ // rememeber the element we process
+ processedElement = element;
+
+ if (!validateElement(element, hasStateMachine)) {
+ return false;
+ }
+
+ } else {
+ if (!m_stateMachines.top().proceed<QXmlName>(name())) {
+ error(QtXmlPatterns::tr("Element %1 is not defined in this scope.").arg(formatKeyword(m_namePool, name())));
+ return false;
+ }
+
+ const XsdTerm::Ptr term = m_stateMachines.top().lastTransition();
+ if (term->isElement()) {
+ const XsdElement::Ptr element(term);
+
+ // rememeber the element we process
+ processedElement = element;
+
+ if (!validateElement(element, hasStateMachine))
+ return false;
+
+ } else {
+ const XsdWildcard::Ptr wildcard(term);
+ if (wildcard->processContents() != XsdWildcard::Skip) {
+ XsdElement::Ptr elementDeclaration = elementByName(name());
+ if (!elementDeclaration) {
+ if (hasAttribute(m_xsiTypeName)) {
+ // This instance document has an element with no definition in the schema
+ // but an explicitly given type, that is fine according to the spec.
+ // We will create an element definition manually here and continue the
+ // normal validation process
+ elementDeclaration = XsdElement::Ptr(new XsdElement());
+ elementDeclaration->setName(name());
+ elementDeclaration->setIsAbstract(false);
+ elementDeclaration->setIsNillable(hasAttribute(m_xsiNilName));
+
+ const QString type = qNameAttribute(m_xsiTypeName);
+ const QXmlName typeName = convertToQName(type);
+
+ const SchemaType::Ptr elementType = typeByName(typeName);
+ if (!elementType) {
+ error(QtXmlPatterns::tr("Specified type %1 is not known to the schema.").arg(formatType(m_namePool, typeName)));
+ return false;
+ }
+ elementDeclaration->setType(elementType);
+ }
+ }
+
+ if (!elementDeclaration) {
+ if (wildcard->processContents() == XsdWildcard::Strict) {
+ error(QtXmlPatterns::tr("Declaration for element %1 does not exist.").arg(formatKeyword(m_namePool->displayName(name()))));
+ return false;
+ } else {
+ // in this case we put a state machine for the xs:anyType on the statemachine stack,
+ // so we accept every content of this element
+
+ createAndPushStateMachine(anyType()->contentType()->particle());
+ hasStateMachine = true;
+ }
+ } else {
+ if (!validateElement(elementDeclaration, hasStateMachine)) {
+ if (wildcard->processContents() == XsdWildcard::Strict) {
+ error(QtXmlPatterns::tr("Element %1 contains invalid content.").arg(formatKeyword(m_namePool->displayName(name()))));
+ return false;
+ }
+ }
+
+ // rememeber the type of that element node
+ m_model->setAssignedType(item().toNodeModelIndex(), elementDeclaration->type());
+ }
+ } else { // wildcard process contents type is Skip
+ // in this case we put a state machine for the xs:anyType on the statemachine stack,
+ // so we accept every content of this element
+
+ const XsdWildcard::Ptr wildcard(new XsdWildcard());
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ wildcard->setProcessContents(XsdWildcard::Skip);
+
+ const XsdParticle::Ptr outerParticle(new XsdParticle());
+ outerParticle->setMinimumOccurs(1);
+ outerParticle->setMaximumOccurs(1);
+
+ const XsdParticle::Ptr innerParticle(new XsdParticle());
+ innerParticle->setMinimumOccurs(0);
+ innerParticle->setMaximumOccursUnbounded(true);
+ innerParticle->setTerm(wildcard);
+
+ const XsdModelGroup::Ptr outerModelGroup(new XsdModelGroup());
+ outerModelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
+ outerModelGroup->setParticles(XsdParticle::List() << innerParticle);
+ outerParticle->setTerm(outerModelGroup);
+
+ createAndPushStateMachine(outerParticle);
+ hasStateMachine = true;
+ }
+ }
+ }
+
+ return true;
+}
+
+void XsdValidatingInstanceReader::createAndPushStateMachine(const XsdParticle::Ptr &particle)
+{
+ XsdStateMachine<XsdTerm::Ptr> stateMachine(m_namePool);
+
+ XsdStateMachineBuilder builder(&stateMachine, m_namePool, XsdStateMachineBuilder::ValidatingMode);
+ const XsdStateMachine<XsdTerm::Ptr>::StateId endState = builder.reset();
+ const XsdStateMachine<XsdTerm::Ptr>::StateId startState = builder.buildParticle(particle, endState);
+ builder.addStartState(startState);
+
+/*
+ QString fileName = QString("/tmp/foo_%1.dot").arg(m_namePool->displayName(complexType->name(m_namePool)));
+ QString pngFileName = QString("/tmp/foo_%1.png").arg(m_namePool->displayName(complexType->name(m_namePool)));
+ QFile file(fileName);
+ file.open(QIODevice::WriteOnly);
+ stateMachine.outputGraph(&file, "Hello");
+ file.close();
+ ::system(QString("dot -Tpng %1 -o%2").arg(fileName).arg(pngFileName).toLatin1().data());
+*/
+
+ stateMachine = stateMachine.toDFA();
+
+ m_stateMachines.push(stateMachine);
+}
+
+bool XsdValidatingInstanceReader::validateElement(const XsdElement::Ptr &declaration, bool &hasStateMachine)
+{
+ // http://www.w3.org/TR/xmlschema11-1/#d0e10998
+
+ bool isNilled = false;
+
+ // 1 tested already, 'declaration' corresponds D
+
+ // 2
+ if (declaration->isAbstract()) {
+ error(QtXmlPatterns::tr("Element %1 is declared as abstract.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+
+ // 3
+ if (!declaration->isNillable()) {
+ if (hasAttribute(m_xsiNilName)) {
+ error(QtXmlPatterns::tr("Element %1 is not nillable.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false; // 3.1
+ }
+ } else {
+ if (hasAttribute(m_xsiNilName)) {
+ const QString value = attribute(m_xsiNilName);
+ const Boolean::Ptr nil = Boolean::fromLexical(value);
+ if (nil->hasError()) {
+ error(QtXmlPatterns::tr("Attribute %1 contains invalid data: %2").arg(formatKeyword(QLatin1String("nil."))).arg(formatData(value)));
+ return false;
+ }
+
+ // 3.2.3
+ if (nil->as<Boolean>()->value() == true) {
+ // 3.2.3.1
+ if (hasChildElement() || hasChildText()) {
+ error(QtXmlPatterns::tr("Element contains content although it is nillable."));
+ return false;
+ }
+
+ // 3.2.3.2
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
+ error(QtXmlPatterns::tr("Fixed value constraint not allowed if element is nillable."));
+ return false;
+ }
+ }
+
+ isNilled = nil->as<Boolean>()->value();
+ }
+ }
+
+ SchemaType::Ptr finalElementType = declaration->type();
+
+ // 4
+ if (hasAttribute(m_xsiTypeName)) {
+ const QString type = qNameAttribute(m_xsiTypeName);
+ const QXmlName typeName = convertToQName(type);
+
+ const SchemaType::Ptr elementType = typeByName(typeName);
+ // 4.1
+ if (!elementType) {
+ error(QtXmlPatterns::tr("Specified type %1 is not known to the schema.").arg(formatType(m_namePool, typeName)));
+ return false;
+ }
+
+ // 4.2
+ SchemaType::DerivationConstraints constraints = 0;
+ if (declaration->disallowedSubstitutions() & NamedSchemaComponent::ExtensionConstraint)
+ constraints |= SchemaType::ExtensionConstraint;
+ if (declaration->disallowedSubstitutions() & NamedSchemaComponent::RestrictionConstraint)
+ constraints |= SchemaType::RestrictionConstraint;
+
+ if (!XsdSchemaHelper::isValidlySubstitutable(elementType, declaration->type(), constraints)) {
+ if (declaration->type()->name(m_namePool) != BuiltinTypes::xsAnyType->name(m_namePool)) { // xs:anyType is a valid substitutable type here
+ error(QtXmlPatterns::tr("Specified type %1 is not validly substitutable with element type %2.").arg(formatType(m_namePool, elementType)).arg(formatType(m_namePool, declaration->type())));
+ return false;
+ }
+ }
+
+ finalElementType = elementType;
+ }
+
+ if (!validateElementType(declaration, finalElementType, isNilled, hasStateMachine))
+ return false;
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateElementType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e11749
+
+ // 1 checked already
+
+ // 2
+ if (type->isComplexType() && type->isDefinedBySchema()) {
+ if (XsdComplexType::Ptr(type)->isAbstract()) {
+ error(QtXmlPatterns::tr("Complex type %1 is not allowed to be abstract.").arg(formatType(m_namePool, type)));
+ return false;
+ }
+ }
+
+ // 3
+ if (type->isSimpleType())
+ return validateElementSimpleType(declaration, type, isNilled); // 3.1
+ else
+ return validateElementComplexType(declaration, type, isNilled, hasStateMachine); // 3.2
+}
+
+bool XsdValidatingInstanceReader::validateElementSimpleType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e11749
+
+ // 3.1.1
+ const QSet<QXmlName> allowedAttributes(QSet<QXmlName>() << m_xsiNilName << m_xsiTypeName << m_xsiSchemaLocationName << m_xsiNoNamespaceSchemaLocationName);
+ QSet<QXmlName> elementAttributes = attributeNames();
+ elementAttributes.subtract(allowedAttributes);
+ if (!elementAttributes.isEmpty()) {
+ error(QtXmlPatterns::tr("Element %1 contains not allowed attributes.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+
+ // 3.1.2
+ if (hasChildElement()) {
+ error(QtXmlPatterns::tr("Element %1 contains not allowed child element.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+
+ // 3.1.3
+ if (!isNilled) {
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(type, m_context);
+
+ QString actualValue;
+ if (hasChildText()) {
+ actualValue = XsdTypeChecker::normalizedValue(text(), facets);
+ } else {
+ if (declaration->valueConstraint())
+ actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ }
+
+ QString errorMsg;
+ AnySimpleType::Ptr boundType;
+
+ const XsdTypeChecker checker(m_context, namespaceBindings(item().toNodeModelIndex()), sourceLocation());
+ if (!checker.isValidString(actualValue, type, errorMsg, &boundType)) {
+ error(QtXmlPatterns::tr("Content of element %1 does not match its type definition: %2.").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg));
+ return false;
+ }
+
+ // additional check
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
+ const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ if (!text().isEmpty() && !checker.valuesAreEqual(actualValue, actualConstraintValue, type)) {
+ error(QtXmlPatterns::tr("Content of element %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+ }
+
+ // 4 checked in validateElement already
+
+ // rememeber the type of that element node
+ m_model->setAssignedType(item().toNodeModelIndex(), type);
+
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(type, m_context);
+ const QString actualValue = XsdTypeChecker::normalizedValue(text(), facets);
+
+ if (BuiltinTypes::xsID->wxsTypeMatches(type)) {
+ addIdIdRefBinding(actualValue, declaration);
+ }
+
+ if (m_idRefsType->wxsTypeMatches(type)) {
+ const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < idRefs.count(); ++i) {
+ m_idRefs.insert(idRefs.at(i));
+ }
+ } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(type)) {
+ m_idRefs.insert(actualValue);
+ }
+
+ return true;
+}
+
+static bool hasIDAttributeUse(const XsdAttributeUse::List &uses)
+{
+ const int count = uses.count();
+ for (int i = 0; i < count; ++i) {
+ if (BuiltinTypes::xsID->wxsTypeMatches(uses.at(i)->attribute()->type()))
+ return true;
+ }
+
+ return false;
+}
+
+bool XsdValidatingInstanceReader::validateElementComplexType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-complex-type
+
+ // 1
+ if (!isNilled) {
+ XsdComplexType::Ptr complexType;
+
+ if (type->isDefinedBySchema()) {
+ complexType = XsdComplexType::Ptr(type);
+ } else {
+ if (type->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool))
+ complexType = anyType();
+ }
+
+ if (complexType) {
+ // 1.1
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
+ if (hasChildText() || hasChildElement()) {
+ error(QtXmlPatterns::tr("Element %1 contains not allowed child content.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+
+ // 1.2
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
+ if (hasChildElement()) {
+ error(QtXmlPatterns::tr("Element %1 contains not allowed child element.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(complexType->contentType()->simpleType(), m_context);
+ QString actualValue;
+ if (hasChildText()) {
+ actualValue = XsdTypeChecker::normalizedValue(text(), facets);
+ } else {
+ if (declaration->valueConstraint())
+ actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ }
+
+ QString errorMsg;
+ AnySimpleType::Ptr boundType;
+ const XsdTypeChecker checker(m_context, namespaceBindings(item().toNodeModelIndex()), sourceLocation());
+ if (!checker.isValidString(actualValue, complexType->contentType()->simpleType(), errorMsg, &boundType)) {
+ error(QtXmlPatterns::tr("Content of element %1 does not match its type definition: %2.").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg));
+ return false;
+ }
+
+ // additional check
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
+ if (!checker.valuesAreEqual(actualValue, declaration->valueConstraint()->value(), boundType)) {
+ error(QtXmlPatterns::tr("Content of element %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+ }
+
+ // 1.3
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) {
+ if (!text().simplified().isEmpty()) {
+ error(QtXmlPatterns::tr("Element %1 contains not allowed text content.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+
+ // 1.4
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly ||
+ complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
+
+ if (complexType->contentType()->particle()) {
+ createAndPushStateMachine(complexType->contentType()->particle());
+ hasStateMachine = true;
+ }
+
+ // additional check
+ if (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
+ if (hasChildElement()) {
+ error(QtXmlPatterns::tr("Element %1 cannot contain other elements, as it has a fixed content.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(complexType->contentType()->simpleType(), m_context);
+ QString actualValue;
+ if (hasChildText()) {
+ actualValue = XsdTypeChecker::normalizedValue(text(), facets);
+ } else {
+ if (declaration->valueConstraint())
+ actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ }
+
+ if (actualValue != declaration->valueConstraint()->value()) {
+ error(QtXmlPatterns::tr("Content of element %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (type->isDefinedBySchema()) {
+ const XsdComplexType::Ptr complexType(type);
+
+ // create a lookup hash for faster access
+ QHash<QXmlName, XsdAttributeUse::Ptr> attributeUseHash;
+ {
+ const XsdAttributeUse::List attributeUses = complexType->attributeUses();
+ for (int i = 0; i < attributeUses.count(); ++i)
+ attributeUseHash.insert(attributeUses.at(i)->attribute()->name(m_namePool), attributeUses.at(i));
+ }
+
+ const QSet<QXmlName> attributes(attributeNames());
+
+ // 3
+ QHashIterator<QXmlName, XsdAttributeUse::Ptr> usesIt(attributeUseHash);
+ while (usesIt.hasNext()) {
+ usesIt.next();
+
+ if (usesIt.value()->isRequired()) {
+ if (!attributes.contains(usesIt.key())) {
+ error(QtXmlPatterns::tr("Element %1 is missing required attribute %2.").arg(formatKeyword(declaration->displayName(m_namePool)))
+ .arg(formatKeyword(m_namePool->displayName(usesIt.key()))));
+ return false;
+ }
+ }
+ }
+
+ bool hasIDAttribute = hasIDAttributeUse(complexType->attributeUses());
+
+ // 2
+ QSetIterator<QXmlName> it(attributes);
+ while (it.hasNext()) {
+ const QXmlName attributeName = it.next();
+
+ // skip builtin attributes
+ if (attributeName == m_xsiNilName ||
+ attributeName == m_xsiTypeName ||
+ attributeName == m_xsiSchemaLocationName ||
+ attributeName == m_xsiNoNamespaceSchemaLocationName)
+ continue;
+
+ // 2.1
+ if (attributeUseHash.contains(attributeName) && (attributeUseHash.value(attributeName)->useType() != XsdAttributeUse::ProhibitedUse)) {
+ if (!validateAttribute(attributeUseHash.value(attributeName), attribute(attributeName)))
+ return false;
+ } else { // 2.2
+ if (complexType->attributeWildcard()) {
+ const XsdWildcard::Ptr wildcard(complexType->attributeWildcard());
+ if (!validateAttributeWildcard(attributeName, wildcard)) {
+ error(QtXmlPatterns::tr("Attribute %1 does not match the attribute wildcard.").arg(formatKeyword(m_namePool->displayName(attributeName))));
+ return false;
+ }
+
+ if (wildcard->processContents() != XsdWildcard::Skip) {
+ const XsdAttribute::Ptr attributeDeclaration = attributeByName(attributeName);
+
+ if (!attributeDeclaration) {
+ if (wildcard->processContents() == XsdWildcard::Strict) {
+ error(QtXmlPatterns::tr("Declaration for attribute %1 does not exist.").arg(formatKeyword(m_namePool->displayName(attributeName))));
+ return false;
+ }
+ } else {
+ if (BuiltinTypes::xsID->wxsTypeMatches(attributeDeclaration->type())) {
+ if (hasIDAttribute) {
+ error(QtXmlPatterns::tr("Element %1 contains two attributes of type %2.")
+ .arg(formatKeyword(declaration->displayName(m_namePool)))
+ .arg(formatKeyword("ID")));
+ return false;
+ }
+
+ hasIDAttribute = true;
+ }
+
+ if (!validateAttribute(attributeDeclaration, attribute(attributeName))) {
+ if (wildcard->processContents() == XsdWildcard::Strict) {
+ error(QtXmlPatterns::tr("Attribute %1 contains invalid content.").arg(formatKeyword(m_namePool->displayName(attributeName))));
+ return false;
+ }
+ }
+ }
+ }
+ } else {
+ error(QtXmlPatterns::tr("Element %1 contains unknown attribute %2.").arg(formatKeyword(declaration->displayName(m_namePool)))
+ .arg(formatKeyword(m_namePool->displayName(attributeName))));
+ return false;
+ }
+ }
+ }
+ }
+
+ // 4
+ // so what?...
+
+ // 5
+ // hmm...
+
+ // 6
+ // TODO: check assertions
+
+ // 7
+ // TODO: check type table restrictions
+
+ // rememeber the type of that element node
+ m_model->setAssignedType(item().toNodeModelIndex(), type);
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateAttribute(const XsdAttributeUse::Ptr &declaration, const QString &value)
+{
+ const AnySimpleType::Ptr attributeType = declaration->attribute()->type();
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(attributeType, m_context);
+
+ const QString actualValue = XsdTypeChecker::normalizedValue(value, facets);
+
+ QString errorMsg;
+ AnySimpleType::Ptr boundType;
+
+ const QXmlNodeModelIndex index = attributeItem(declaration->attribute()->name(m_namePool)).toNodeModelIndex();
+
+ const XsdTypeChecker checker(m_context, namespaceBindings(index), sourceLocation());
+ if (!checker.isValidString(actualValue, attributeType, errorMsg, &boundType)) {
+ error(QtXmlPatterns::tr("Content of attribute %1 does not match its type definition: %2.").arg(formatKeyword(declaration->attribute()->displayName(m_namePool))).arg(errorMsg));
+ return false;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-au
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
+ const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ if (!checker.valuesAreEqual(actualValue, actualConstraintValue, attributeType)) {
+ error(QtXmlPatterns::tr("Content of attribute %1 does not match defined value constraint.").arg(formatKeyword(declaration->attribute()->displayName(m_namePool))));
+ return false;
+ }
+ }
+
+ if (BuiltinTypes::xsID->wxsTypeMatches(declaration->attribute()->type())) {
+ addIdIdRefBinding(actualValue, declaration->attribute());
+ }
+
+ if (m_idRefsType->wxsTypeMatches(declaration->attribute()->type())) {
+ const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < idRefs.count(); ++i)
+ m_idRefs.insert(idRefs.at(i));
+ } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(declaration->attribute()->type())) {
+ m_idRefs.insert(actualValue);
+ }
+
+ m_model->setAssignedType(index, declaration->attribute()->type());
+ m_model->setAssignedAttribute(index, declaration->attribute());
+
+ return true;
+}
+
+//TODO: merge that with the method above
+bool XsdValidatingInstanceReader::validateAttribute(const XsdAttribute::Ptr &declaration, const QString &value)
+{
+ const AnySimpleType::Ptr attributeType = declaration->type();
+ const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(attributeType, m_context);
+
+ const QString actualValue = XsdTypeChecker::normalizedValue(value, facets);
+
+ QString errorMsg;
+ AnySimpleType::Ptr boundType;
+
+ const QXmlNodeModelIndex index = attributeItem(declaration->name(m_namePool)).toNodeModelIndex();
+
+ const XsdTypeChecker checker(m_context, namespaceBindings(index), sourceLocation());
+ if (!checker.isValidString(actualValue, attributeType, errorMsg, &boundType)) {
+ error(QtXmlPatterns::tr("Content of attribute %1 does not match its type definition: %2.").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg));
+ return false;
+ }
+
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-au
+ if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Fixed) {
+ const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
+ if (!checker.valuesAreEqual(actualValue, actualConstraintValue, attributeType)) {
+ error(QtXmlPatterns::tr("Content of attribute %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+
+ if (BuiltinTypes::xsID->wxsTypeMatches(declaration->type())) {
+ addIdIdRefBinding(actualValue, declaration);
+ }
+
+ if (m_idRefsType->wxsTypeMatches(declaration->type())) {
+ const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ for (int i = 0; i < idRefs.count(); ++i)
+ m_idRefs.insert(idRefs.at(i));
+ } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(declaration->type())) {
+ m_idRefs.insert(actualValue);
+ }
+
+ m_model->setAssignedType(index, declaration->type());
+ m_model->setAssignedAttribute(index, declaration);
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateAttributeWildcard(const QXmlName &attributeName, const XsdWildcard::Ptr &wildcard)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#cvc-wildcard
+
+ // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
+ QXmlName name(attributeName);
+ if (name.namespaceURI() == StandardNamespaces::empty) {
+ name.setNamespaceURI(m_namePool->allocateNamespace(XsdWildcard::absentNamespace()));
+ }
+
+ return XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, m_namePool);
+}
+
+bool XsdValidatingInstanceReader::validateIdentityConstraint(const XsdElement::Ptr &element, const QXmlItem &currentItem)
+{
+ const XsdIdentityConstraint::List constraints = element->identityConstraints();
+
+ for (int i = 0; i < constraints.count(); ++i) {
+ const XsdIdentityConstraint::Ptr constraint = constraints.at(i);
+
+ TargetNode::Set targetNodeSet, qualifiedNodeSet;
+ selectNodeSets(element, currentItem, constraint, targetNodeSet, qualifiedNodeSet);
+
+ if (constraint->category() == XsdIdentityConstraint::Unique) {
+ if (!validateUniqueIdentityConstraint(element, constraint, qualifiedNodeSet))
+ return false;
+ } else if (constraint->category() == XsdIdentityConstraint::Key) {
+ if (!validateKeyIdentityConstraint(element, constraint, targetNodeSet, qualifiedNodeSet))
+ return false;
+ }
+ }
+
+ // we do the keyref check in a separated run to make sure that all keys are available
+ for (int i = 0; i < constraints.count(); ++i) {
+ const XsdIdentityConstraint::Ptr constraint = constraints.at(i);
+ if (constraint->category() == XsdIdentityConstraint::KeyReference) {
+ TargetNode::Set targetNodeSet, qualifiedNodeSet;
+ selectNodeSets(element, currentItem, constraint, targetNodeSet, qualifiedNodeSet);
+
+ if (!validateKeyRefIdentityConstraint(element, constraint, qualifiedNodeSet))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateUniqueIdentityConstraint(const XsdElement::Ptr&, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243
+
+ // 4.1
+ const XsdSchemaSourceLocationReflection reflection(sourceLocation());
+
+ QSetIterator<TargetNode> it(qualifiedNodeSet);
+ while (it.hasNext()) {
+ const TargetNode node = it.next();
+ QSetIterator<TargetNode> innerIt(qualifiedNodeSet);
+ while (innerIt.hasNext()) {
+ const TargetNode innerNode = innerIt.next();
+
+ if (node == innerNode) // do not compare with ourself
+ continue;
+
+ if (node.fieldsAreEqual(innerNode, m_namePool, m_context, &reflection)) {
+ error(QtXmlPatterns::tr("Non-unique value found for constraint %1.").arg(formatKeyword(constraint->displayName(m_namePool))));
+ return false;
+ }
+ }
+ }
+
+ m_idcKeys.insert(constraint->name(m_namePool), qualifiedNodeSet);
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateKeyIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &targetNodeSet, const TargetNode::Set &qualifiedNodeSet)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243
+
+ // 4.2
+ const XsdSchemaSourceLocationReflection reflection(sourceLocation());
+
+ // 4.2.1
+ if (targetNodeSet.count() != qualifiedNodeSet.count()) {
+ error(QtXmlPatterns::tr("Key constraint %1 contains absent fields.").arg(formatKeyword(constraint->displayName(m_namePool))));
+ return false;
+ }
+
+ // 4.2.2
+ if (!validateUniqueIdentityConstraint(element, constraint, qualifiedNodeSet))
+ return false;
+
+ // 4.2.3
+ QSetIterator<TargetNode> it(qualifiedNodeSet);
+ while (it.hasNext()) {
+ const TargetNode node = it.next();
+ const QVector<QXmlItem> fieldItems = node.fieldItems();
+ for (int i = 0; i < fieldItems.count(); ++i) {
+ const QXmlNodeModelIndex index = fieldItems.at(i).toNodeModelIndex();
+ if (m_model->kind(index) == QXmlNodeModelIndex::Element) {
+ const XsdElement::Ptr declaration = m_model->assignedElement(index);
+ if (declaration && declaration->isNillable()) {
+ error(QtXmlPatterns::tr("Key constraint %1 contains references nillable element %2.")
+ .arg(formatKeyword(constraint->displayName(m_namePool)))
+ .arg(formatKeyword(declaration->displayName(m_namePool))));
+ return false;
+ }
+ }
+ }
+ }
+
+ m_idcKeys.insert(constraint->name(m_namePool), qualifiedNodeSet);
+
+ return true;
+}
+
+bool XsdValidatingInstanceReader::validateKeyRefIdentityConstraint(const XsdElement::Ptr&, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet)
+{
+ // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243
+
+ // 4.3
+ const XsdSchemaSourceLocationReflection reflection(sourceLocation());
+
+ const TargetNode::Set keySet = m_idcKeys.value(constraint->referencedKey()->name(m_namePool));
+
+ QSetIterator<TargetNode> it(qualifiedNodeSet);
+ while (it.hasNext()) {
+ const TargetNode node = it.next();
+
+ bool foundMatching = false;
+
+ QSetIterator<TargetNode> keyIt(keySet);
+ while (keyIt.hasNext()) {
+ const TargetNode keyNode = keyIt.next();
+
+ if (node.fieldsAreEqual(keyNode, m_namePool, m_context, &reflection)) {
+ foundMatching = true;
+ break;
+ }
+ }
+
+ if (!foundMatching) {
+ error(QtXmlPatterns::tr("No referenced value found for key reference %1.").arg(formatKeyword(constraint->displayName(m_namePool))));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+QXmlQuery XsdValidatingInstanceReader::createXQuery(const QList<QXmlName> &namespaceBindings, const QXmlItem &contextNode, const QString &queryString) const
+{
+ // create a public name pool from our name pool
+ QXmlNamePool namePool(m_namePool.data());
+
+ // the QXmlQuery shall work with the same name pool as we do
+ QXmlQuery query(namePool);
+
+ // add additional namespace bindings
+ QXmlQueryPrivate *queryPrivate = query.d;
+
+ for (int i = 0; i < namespaceBindings.count(); ++i) {
+ if (!namespaceBindings.at(i).prefix() == StandardPrefixes::empty)
+ queryPrivate->addAdditionalNamespaceBinding(namespaceBindings.at(i));
+ }
+
+ // set the context node for that query and the query string
+ query.setFocus(contextNode);
+ query.setQuery(queryString, m_documentUri);
+
+ return query;
+}
+
+bool XsdValidatingInstanceReader::selectNodeSets(const XsdElement::Ptr&, const QXmlItem &currentItem, const XsdIdentityConstraint::Ptr &constraint, TargetNode::Set &targetNodeSet, TargetNode::Set &qualifiedNodeSet)
+{
+ // at first select all target nodes
+ const XsdXPathExpression::Ptr selector = constraint->selector();
+ const XsdXPathExpression::List fields = constraint->fields();
+
+ QXmlQuery query = createXQuery(selector->namespaceBindings(), currentItem, selector->expression());
+
+ QXmlResultItems resultItems;
+ query.evaluateTo(&resultItems);
+
+ // now we iterate over all target nodes and select the fields for each node
+ QXmlItem item(resultItems.next());
+ while (!item.isNull()) {
+
+ TargetNode targetNode(item);
+
+ for (int i = 0; i < fields.count(); ++i) {
+ const XsdXPathExpression::Ptr field = fields.at(i);
+ QXmlQuery fieldQuery = createXQuery(field->namespaceBindings(), item, field->expression());
+
+ QXmlResultItems fieldResultItems;
+ fieldQuery.evaluateTo(&fieldResultItems);
+
+ // copy result into vetor for better testing...
+ QVector<QXmlItem> fieldVector;
+ QXmlItem fieldItem(fieldResultItems.next());
+ while (!fieldItem.isNull()) {
+ fieldVector.append(fieldItem);
+ fieldItem = fieldResultItems.next();
+ }
+
+ if (fieldVector.count() > 1) {
+ error(QtXmlPatterns::tr("More than one value found for field %1.").arg(formatData(field->expression())));
+ return false;
+ }
+
+ if (fieldVector.count() == 1) {
+ fieldItem = fieldVector.first();
+
+ const QXmlNodeModelIndex index = fieldItem.toNodeModelIndex();
+ const SchemaType::Ptr type = m_model->assignedType(index);
+
+ bool typeOk = true;
+ if (type->isComplexType()) {
+ if (type->isDefinedBySchema()) {
+ if (XsdComplexType::Ptr(type)->contentType()->variety() != XsdComplexType::ContentType::Simple)
+ typeOk = false;
+ } else {
+ typeOk = false;
+ }
+ }
+ if (!typeOk) {
+ error(QtXmlPatterns::tr("Field %1 has no simple type.").arg(formatData(field->expression())));
+ return false;
+ }
+
+ SchemaType::Ptr targetType = type;
+ QString value = m_model->stringValue(fieldItem.toNodeModelIndex());
+
+ if (type->isDefinedBySchema()) {
+ if (type->isSimpleType())
+ targetType = XsdSimpleType::Ptr(type)->primitiveType();
+ else
+ targetType = XsdComplexType::Ptr(type)->contentType()->simpleType();
+ } else {
+ if (BuiltinTypes::xsAnySimpleType->name(m_namePool) == type->name(m_namePool)) {
+ targetType = BuiltinTypes::xsString;
+ value = QLatin1String("___anySimpleType_value");
+ }
+ }
+
+ // if it is xs:QName derived type, we normalize the name content
+ // and do a string comparison
+ if (BuiltinTypes::xsQName->wxsTypeMatches(type)) {
+ targetType = BuiltinTypes::xsString;
+
+ const QXmlName qName = convertToQName(value.trimmed());
+ value = QString::fromLatin1("%1:%2").arg(m_namePool->stringForNamespace(qName.namespaceURI())).arg(m_namePool->stringForLocalName(qName.localName()));
+ }
+
+ targetNode.addField(fieldItem, value, targetType);
+ } else {
+ // we add an empty entry here, that makes comparison easier later on
+ targetNode.addField(QXmlItem(), QString(), SchemaType::Ptr());
+ }
+ }
+
+ targetNodeSet.insert(targetNode);
+
+ item = resultItems.next();
+ }
+
+ // copy all items from target node set to qualified node set, that have no empty fields
+ QSetIterator<TargetNode> it(targetNodeSet);
+ while (it.hasNext()) {
+ const TargetNode node = it.next();
+ if (node.emptyFieldsCount() == 0)
+ qualifiedNodeSet.insert(node);
+ }
+
+ return true;
+}
+
+XsdElement::Ptr XsdValidatingInstanceReader::elementByName(const QXmlName &name) const
+{
+ return m_schema->element(name);
+}
+
+XsdAttribute::Ptr XsdValidatingInstanceReader::attributeByName(const QXmlName &name) const
+{
+ return m_schema->attribute(name);
+}
+
+SchemaType::Ptr XsdValidatingInstanceReader::typeByName(const QXmlName &name) const
+{
+ const SchemaType::Ptr type = m_schema->type(name);
+ if (type)
+ return type;
+
+ return m_context->schemaTypeFactory()->createSchemaType(name);
+}
+
+void XsdValidatingInstanceReader::addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding)
+{
+ if (!m_model->idIdRefBindings(id).isEmpty()) {
+ error(QtXmlPatterns::tr("ID value '%1' is not unique.").arg(formatKeyword(id)));
+ return;
+ }
+
+ m_model->addIdIdRefBinding(id, binding);
+}
+
+QString XsdValidatingInstanceReader::qNameAttribute(const QXmlName &attributeName)
+{
+ const QString value = attribute(attributeName).simplified();
+ if (!XPathHelper::isQName(value)) {
+ error(QtXmlPatterns::tr("'%1' attribute contains invalid QName content: %2.").arg(m_namePool->displayName(attributeName)).arg(formatData(value)));
+ return QString();
+ } else {
+ return value;
+ }
+}
+
+XsdComplexType::Ptr XsdValidatingInstanceReader::anyType()
+{
+ if (m_anyType)
+ return m_anyType;
+
+ const XsdWildcard::Ptr wildcard(new XsdWildcard());
+ wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
+ wildcard->setProcessContents(XsdWildcard::Lax);
+
+ const XsdParticle::Ptr outerParticle(new XsdParticle());
+ outerParticle->setMinimumOccurs(1);
+ outerParticle->setMaximumOccurs(1);
+
+ const XsdParticle::Ptr innerParticle(new XsdParticle());
+ innerParticle->setMinimumOccurs(0);
+ innerParticle->setMaximumOccursUnbounded(true);
+ innerParticle->setTerm(wildcard);
+
+ const XsdModelGroup::Ptr outerModelGroup(new XsdModelGroup());
+ outerModelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
+ outerModelGroup->setParticles(XsdParticle::List() << innerParticle);
+ outerParticle->setTerm(outerModelGroup);
+
+ m_anyType = XsdComplexType::Ptr(new XsdComplexType());
+ m_anyType->setName(BuiltinTypes::xsAnyType->name(m_namePool));
+ m_anyType->setDerivationMethod(XsdComplexType::DerivationRestriction);
+ m_anyType->contentType()->setVariety(XsdComplexType::ContentType::Mixed);
+ m_anyType->contentType()->setParticle(outerParticle);
+ m_anyType->setAttributeWildcard(wildcard);
+ m_anyType->setIsAbstract(false);
+
+ return m_anyType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h
new file mode 100644
index 0000000..4dc736a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdValidatingInstanceReader_H
+#define Patternist_XsdValidatingInstanceReader_H
+
+#include "qxsdidchelper_p.h"
+#include "qxsdinstancereader_p.h"
+#include "qxsdstatemachine_p.h"
+#include "qxsdvalidatedxmlnodemodel_p.h"
+
+#include <QtCore/QStack>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QXmlQuery;
+
+namespace QPatternist
+{
+ /**
+ * @short The validating schema instance reader.
+ *
+ * This class reads in a xml instance document from a QAbstractXmlNodeModel and
+ * validates it against a given xml schema.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdValidatingInstanceReader : public XsdInstanceReader
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdValidatingInstanceReader> Ptr;
+
+ /**
+ * Creates a new validating instance reader that reads the data from
+ * the given @p model.
+ *
+ * @param model The model the data shall be read from.
+ * @param documentUri The uri of the document the model is from.
+ * @param context The context that is used to report errors etc.
+ */
+ XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context);
+
+ /**
+ * Adds a new @p schema to the pool of schemas that shall be used
+ * for validation.
+ * The schema is located at the given @p url.
+ */
+ void addSchema(const XsdSchema::Ptr &schema, const QUrl &url);
+
+ /**
+ * Reads and validates the instance document.
+ */
+ bool read();
+
+ private:
+ /**
+ * Loads a schema with the given @p targetNamespace from the given @p location
+ * and adds it to the pool of schemas that are used for validation.
+ *
+ * This method is used to load schemas defined in the xsi:schemaLocation or
+ * xsi:noNamespaceSchemaLocation attributes in the instance document.
+ */
+ bool loadSchema(const QString &targetNamespace, const QUrl &location);
+
+ /**
+ * Reports an error via the report context.
+ */
+ void error(const QString &msg) const;
+
+ /**
+ * Validates the current element tag of the instance document.
+ *
+ * @param hasStateMachine Used to remember whether this element represents the start tag
+ * of a complex type and therefor pushes a new state machine on the stack.
+ * @param element Used to remember which element has been validated in this step.
+ */
+ bool validate(bool &hasStateMachine, XsdElement::Ptr &element);
+
+ /**
+ * Validates the current tag of the instance document against the given element @p declaration.
+ *
+ * @param declaration The element declaration to validate against.
+ * @param hasStateMachine Used to remember whether this element represents the start tag
+ * of a complex type and therefor pushes a new state machine on the stack.
+ */
+ bool validateElement(const XsdElement::Ptr &declaration, bool &hasStateMachine);
+
+ /**
+ * Validates the current tag of the instance document against the given @p type of the element @p declaration.
+ *
+ * @param declaration The element declaration to validate against.
+ * @param type The type to validate against.
+ * @param isNilled Defines whether the element is nilled by the instance document.
+ * @param hasStateMachine Used to remember whether this element represents the start tag
+ * of a complex type and therefor pushes a new state machine on the stack.
+ *
+ * @note The @p type can differ from the element @p declaration type if the instance document has defined
+ * it via xsi:type attribute.
+ */
+ bool validateElementType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine);
+
+ /**
+ * Validates the current tag of the instance document against the given simple @p type of the element @p declaration.
+ *
+ * @param declaration The element declaration to validate against.
+ * @param type The type to validate against.
+ * @param isNilled Defines whether the element is nilled by the instance document.
+ *
+ * @note The @p type can differ from the element @p declaration type if the instance document has defined
+ * it via xsi:type attribute.
+ */
+ bool validateElementSimpleType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled);
+
+ /**
+ * Validates the current tag of the instance document against the given complex @p type of the element @p declaration.
+ *
+ * @param declaration The element declaration to validate against.
+ * @param type The type to validate against.
+ * @param isNilled Defines whether the element is nilled by the instance document.
+ * @param hasStateMachine Used to remember whether this element represents the start tag
+ * of a complex type and therefor pushes a new state machine on the stack.
+ *
+ * @note The @p type can differ from the element @p declaration type if the instance document has defined
+ * it via xsi:type attribute.
+ */
+ bool validateElementComplexType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine);
+
+ /**
+ * Validates the given @p value against the attribute use @p declaration.
+ */
+ bool validateAttribute(const XsdAttributeUse::Ptr &declaration, const QString &value);
+
+ /**
+ * Validates the given @p value against the attribute @p declaration.
+ */
+ bool validateAttribute(const XsdAttribute::Ptr &declaration, const QString &value);
+
+ /**
+ * Validates the given @p attributeName against the @p wildcard.
+ */
+ bool validateAttributeWildcard(const QXmlName &attributeName, const XsdWildcard::Ptr &wildcard);
+
+ /**
+ * Validates the identity constraints of an @p element.
+ */
+ bool validateIdentityConstraint(const XsdElement::Ptr &element, const QXmlItem &currentItem);
+
+ /**
+ * Validates the <em>unique</em> identity @p constraint of the @p element.
+ */
+ bool validateUniqueIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet);
+
+ /**
+ * Validates the <em>key</em> identity @p constraint of the @p element.
+ */
+ bool validateKeyIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &targetNodeSet, const TargetNode::Set &qualifiedNodeSet);
+
+ /**
+ * Validates the <em>keyref</em> identity @p constraint of the @p element.
+ */
+ bool validateKeyRefIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet);
+
+ /**
+ * Selects two sets of nodes that match the given identity @p constraint.
+ *
+ * @param element The element the identity constraint belongs to.
+ * @param currentItem The current element that will be used as focus for the XQuery.
+ * @param constraint The constraint (selector and fields) that describe the two sets.
+ * @param targetNodeSet The target node set as defined by the schema specification.
+ * @param qualifiedNodeSet The qualified node set as defined by the schema specification.
+ */
+ bool selectNodeSets(const XsdElement::Ptr &element, const QXmlItem &currentItem, const XsdIdentityConstraint::Ptr &constraint, TargetNode::Set &targetNodeSet, TargetNode::Set &qualifiedNodeSet);
+
+ /**
+ * Creates an QXmlQuery object with the defined @p namespaceBindings that has the @p contextNode as focus
+ * and will execute @p query.
+ */
+ QXmlQuery createXQuery(const QList<QXmlName> &namespaceBindings, const QXmlItem &contextNode, const QString &query) const;
+
+ /**
+ * Returns the element declaration with the given @p name from the pool of all schemas.
+ */
+ XsdElement::Ptr elementByName(const QXmlName &name) const;
+
+ /**
+ * Returns the attribute declaration with the given @p name from the pool of all schemas.
+ */
+ XsdAttribute::Ptr attributeByName(const QXmlName &name) const;
+
+ /**
+ * Returns the type declaration with the given @p name from the pool of all schemas.
+ */
+ SchemaType::Ptr typeByName(const QXmlName &name) const;
+
+ /**
+ * Adds the ID/IDREF binding to the validated model and checks for duplicates.
+ */
+ void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding);
+
+ /**
+ * Helper method that reads an attribute of type xs:QName and does
+ * syntax checking.
+ */
+ QString qNameAttribute(const QXmlName &attributeName);
+
+ /**
+ * Returns the xs:anyType that is used to build up the state machine.
+ * We need that as the BuiltinTypes::xsAnyType is not a XsdComplexType.
+ */
+ XsdComplexType::Ptr anyType();
+
+ /**
+ * Helper method that creates a state machine for the given @p particle
+ * and pushes it on the state machine stack.
+ */
+ void createAndPushStateMachine(const XsdParticle::Ptr &particle);
+
+ typedef QHash<QUrl, QStringList> MergedSchemas;
+ typedef QHashIterator<QUrl, QStringList> MergedSchemasIterator;
+
+ XsdValidatedXmlNodeModel::Ptr m_model;
+ MergedSchemas m_mergedSchemas;
+ XsdSchema::Ptr m_schema;
+ const NamePool::Ptr m_namePool;
+ const QXmlName m_xsiNilName;
+ const QXmlName m_xsiTypeName;
+ const QXmlName m_xsiSchemaLocationName;
+ const QXmlName m_xsiNoNamespaceSchemaLocationName;
+
+ QStack<XsdStateMachine<XsdTerm::Ptr> > m_stateMachines;
+ QUrl m_documentUri;
+ XsdComplexType::Ptr m_anyType;
+ QSet<QString> m_processedNamespaces;
+ QSet<QString> m_processedSchemaLocations;
+ QSet<QString> m_idRefs;
+ QHash<QXmlName, TargetNode::Set> m_idcKeys;
+ SchemaType::Ptr m_idRefsType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdwildcard.cpp b/src/xmlpatterns/schema/qxsdwildcard.cpp
new file mode 100644
index 0000000..abf490e
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdwildcard.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdwildcard_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QString XsdWildcard::absentNamespace()
+{
+ return QLatin1String("__ns_absent");
+}
+
+void XsdWildcard::NamespaceConstraint::setVariety(Variety variety)
+{
+ m_variety = variety;
+}
+
+XsdWildcard::NamespaceConstraint::Variety XsdWildcard::NamespaceConstraint::variety() const
+{
+ return m_variety;
+}
+
+void XsdWildcard::NamespaceConstraint::setNamespaces(const QSet<QString> &namespaces)
+{
+ m_namespaces = namespaces;
+}
+
+QSet<QString> XsdWildcard::NamespaceConstraint::namespaces() const
+{
+ return m_namespaces;
+}
+
+void XsdWildcard::NamespaceConstraint::setDisallowedNames(const QSet<QString> &names)
+{
+ m_disallowedNames = names;
+}
+
+QSet<QString> XsdWildcard::NamespaceConstraint::disallowedNames() const
+{
+ return m_disallowedNames;
+}
+
+XsdWildcard::XsdWildcard()
+ : m_namespaceConstraint(new NamespaceConstraint())
+ , m_processContents(Strict)
+{
+ m_namespaceConstraint->setVariety(NamespaceConstraint::Any);
+}
+
+bool XsdWildcard::isWildcard() const
+{
+ return true;
+}
+
+void XsdWildcard::setNamespaceConstraint(const NamespaceConstraint::Ptr &namespaceConstraint)
+{
+ m_namespaceConstraint = namespaceConstraint;
+}
+
+XsdWildcard::NamespaceConstraint::Ptr XsdWildcard::namespaceConstraint() const
+{
+ return m_namespaceConstraint;
+}
+
+void XsdWildcard::setProcessContents(ProcessContents contents)
+{
+ m_processContents = contents;
+}
+
+XsdWildcard::ProcessContents XsdWildcard::processContents() const
+{
+ return m_processContents;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdwildcard_p.h b/src/xmlpatterns/schema/qxsdwildcard_p.h
new file mode 100644
index 0000000..8940f13
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdwildcard_p.h
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdWildcard_H
+#define Patternist_XsdWildcard_H
+
+#include "qxsdterm_p.h"
+
+#include <QtCore/QSet>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD wildcard object.
+ *
+ * This class represents the <em>wildcard</em> object of a XML schema as described
+ * <a href="http://www.w3.org/TR/xmlschema11-1/#Wildcards">here</a>.
+ *
+ * It contains information from either an <em>any</em> object or an <em>anyAttribute</em> object.
+ *
+ * @see <a href="http://www.w3.org/Submission/2004/SUBM-xmlschema-api-20040309/xml-schema-api.html#Interface-XSWildcard">XML Schema API reference</a>
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ */
+ class XsdWildcard : public XsdTerm
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdWildcard> Ptr;
+
+ /**
+ * Defines the absent namespace that is used in wildcards.
+ */
+ static QString absentNamespace();
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#w-namespace_constraint">namespace constraint</a> of the wildcard.
+ */
+ class NamespaceConstraint : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<NamespaceConstraint> Ptr;
+
+ /**
+ * Describes the variety of the namespace constraint.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#nc-variety">Variety Definition</a>
+ */
+ enum Variety
+ {
+ Any, ///< Any namespace is allowed.
+ Enumeration, ///< Namespaces in the namespaces set are allowed.
+ Not ///< Namespaces in the namespaces set are not allowed.
+ };
+
+ /**
+ * Sets the @p variety of the namespace constraint.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#nc-variety">Variety Definition</a>
+ */
+ void setVariety(Variety variety);
+
+ /**
+ * Returns the variety of the namespace constraint.
+ */
+ Variety variety() const;
+
+ /**
+ * Sets the set of @p namespaces of the namespace constraint.
+ */
+ void setNamespaces(const QSet<QString> &namespaces);
+
+ /**
+ * Returns the set of namespaces of the namespace constraint.
+ */
+ QSet<QString> namespaces() const;
+
+ /**
+ * Sets the set of disallowed @p names of the namespace constraint.
+ */
+ void setDisallowedNames(const QSet<QString> &names);
+
+ /**
+ * Returns the set of disallowed names of the namespace constraint.
+ */
+ QSet<QString> disallowedNames() const;
+
+ private:
+ Variety m_variety;
+ QSet<QString> m_namespaces;
+ QSet<QString> m_disallowedNames;
+ };
+
+ /**
+ * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#w-process_contents">type of content processing</a> of the wildcard.
+ */
+ enum ProcessContents
+ {
+ Strict, ///< There must be a top-level declaration for the item available, or the item must have an xsi:type, and the item must be valid as appropriate.
+ Lax, ///< If the item has a uniquely determined declaration available, it must be valid with respect to that definition.
+ Skip ///< No constraints at all: the item must simply be well-formed XML.
+ };
+
+ /**
+ * Creates a new wildcard object.
+ */
+ XsdWildcard();
+
+ /**
+ * Returns always @c true, used to avoid dynamic casts.
+ */
+ virtual bool isWildcard() const;
+
+ /**
+ * Sets the namespace @p constraint of the wildcard.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#w-namespace_constraint">Namespace Constraint Definition</a>
+ */
+ void setNamespaceConstraint(const NamespaceConstraint::Ptr &constraint);
+
+ /**
+ * Returns the namespace constraint of the wildcard.
+ */
+ NamespaceConstraint::Ptr namespaceConstraint() const;
+
+ /**
+ * Sets the process @p contents of the wildcard.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#w-process_contents">Process Contents Definition</a>
+ */
+ void setProcessContents(ProcessContents contents);
+
+ /**
+ * Returns the process contents of the wildcard.
+ */
+ ProcessContents processContents() const;
+
+ private:
+ NamespaceConstraint::Ptr m_namespaceConstraint;
+ ProcessContents m_processContents;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/qxsdxpathexpression.cpp b/src/xmlpatterns/schema/qxsdxpathexpression.cpp
new file mode 100644
index 0000000..d5b4f1a
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdxpathexpression.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxsdxpathexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+void XsdXPathExpression::setNamespaceBindings(const QList<QXmlName> &set)
+{
+ m_namespaceBindings = set;
+}
+
+QList<QXmlName> XsdXPathExpression::namespaceBindings() const
+{
+ return m_namespaceBindings;
+}
+
+void XsdXPathExpression::setDefaultNamespace(const AnyURI::Ptr &defaultNs)
+{
+ m_defaultNamespace = defaultNs;
+}
+
+AnyURI::Ptr XsdXPathExpression::defaultNamespace() const
+{
+ return m_defaultNamespace;
+}
+
+void XsdXPathExpression::setBaseURI(const AnyURI::Ptr &uri)
+{
+ m_baseURI = uri;
+}
+
+AnyURI::Ptr XsdXPathExpression::baseURI() const
+{
+ return m_baseURI;
+}
+
+void XsdXPathExpression::setExpression(const QString &expression)
+{
+ m_expression = expression;
+}
+
+QString XsdXPathExpression::expression() const
+{
+ return m_expression;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/schema/qxsdxpathexpression_p.h b/src/xmlpatterns/schema/qxsdxpathexpression_p.h
new file mode 100644
index 0000000..8685da5
--- /dev/null
+++ b/src/xmlpatterns/schema/qxsdxpathexpression_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XsdXPathExpression_H
+#define Patternist_XsdXPathExpression_H
+
+#include "qanyuri_p.h"
+#include "qnamedschemacomponent_p.h"
+#include "qxsdannotated_p.h"
+
+#include <QtCore/QList>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a XSD assertion object.
+ *
+ * @ingroup Patternist_schema
+ * @author Tobias Koenig <tobias.koenig@nokia.com>
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#x">XPathExpression Definition</a>
+ */
+ class XsdXPathExpression : public NamedSchemaComponent, public XsdAnnotated
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<XsdXPathExpression> Ptr;
+ typedef QList<XsdXPathExpression::Ptr> List;
+
+ /**
+ * Sets the list of namespace @p bindings of the XPath expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#x-namespace_bindings">Namespace Bindings Definition</a>
+ *
+ * @note We can't use a QSet<QXmlName> here, as the hash method does not take the prefix
+ * in account, so we loose entries.
+ */
+ void setNamespaceBindings(const QList<QXmlName> &bindings);
+
+ /**
+ * Returns the list of namespace bindings of the XPath expression.
+ */
+ QList<QXmlName> namespaceBindings() const;
+
+ /**
+ * Sets the default namespace of the XPath expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#x-default_namespace">Default Namespace Definition</a>
+ */
+ void setDefaultNamespace(const AnyURI::Ptr &defaultNamespace);
+
+ /**
+ * Returns the default namespace of the XPath expression.
+ */
+ AnyURI::Ptr defaultNamespace() const;
+
+ /**
+ * Sets the base @p uri of the XPath expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#x-base_URI">Base URI Definition</a>
+ */
+ void setBaseURI(const AnyURI::Ptr &uri);
+
+ /**
+ * Returns the base uri of the XPath expression.
+ */
+ AnyURI::Ptr baseURI() const;
+
+ /**
+ * Sets the @p expression string of the XPath expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xmlschema11-1/#x-expression">Expression Definition</a>
+ */
+ void setExpression(const QString &expression);
+
+ /**
+ * Returns the expression string of the XPath expression.
+ */
+ QString expression() const;
+
+ private:
+ QList<QXmlName> m_namespaceBindings;
+ AnyURI::Ptr m_defaultNamespace;
+ AnyURI::Ptr m_baseURI;
+ QString m_expression;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/schema/schema.pri b/src/xmlpatterns/schema/schema.pri
new file mode 100644
index 0000000..b00d64b
--- /dev/null
+++ b/src/xmlpatterns/schema/schema.pri
@@ -0,0 +1,93 @@
+HEADERS += $$PWD/qnamespacesupport_p.h \
+ $$PWD/qxsdalternative_p.h \
+ $$PWD/qxsdannotated_p.h \
+ $$PWD/qxsdannotation_p.h \
+ $$PWD/qxsdapplicationinformation_p.h \
+ $$PWD/qxsdassertion_p.h \
+ $$PWD/qxsdattribute_p.h \
+ $$PWD/qxsdattributereference_p.h \
+ $$PWD/qxsdattributeterm_p.h \
+ $$PWD/qxsdattributeuse_p.h \
+ $$PWD/qxsdattributegroup_p.h \
+ $$PWD/qxsdcomplextype_p.h \
+ $$PWD/qxsddocumentation_p.h \
+ $$PWD/qxsdelement_p.h \
+ $$PWD/qxsdfacet_p.h \
+ $$PWD/qxsdidcache_p.h \
+ $$PWD/qxsdidchelper_p.h \
+ $$PWD/qxsdidentityconstraint_p.h \
+ $$PWD/qxsdinstancereader_p.h \
+ $$PWD/qxsdmodelgroup_p.h \
+ $$PWD/qxsdnotation_p.h \
+ $$PWD/qxsdparticle_p.h \
+ $$PWD/qxsdparticlechecker_p.h \
+ $$PWD/qxsdreference_p.h \
+ $$PWD/qxsdsimpletype_p.h \
+ $$PWD/qxsdschema_p.h \
+ $$PWD/qxsdschemachecker_p.h \
+ $$PWD/qxsdschemacontext_p.h \
+ $$PWD/qxsdschemadebugger_p.h \
+ $$PWD/qxsdschemahelper_p.h \
+ $$PWD/qxsdschemamerger_p.h \
+ $$PWD/qxsdschemaparser_p.h \
+ $$PWD/qxsdschemaparsercontext_p.h \
+ $$PWD/qxsdschemaresolver_p.h \
+ $$PWD/qxsdschematoken_p.h \
+ $$PWD/qxsdschematypesfactory_p.h \
+ $$PWD/qxsdstatemachine_p.h \
+ $$PWD/qxsdstatemachinebuilder_p.h \
+ $$PWD/qxsdterm_p.h \
+ $$PWD/qxsdtypechecker_p.h \
+ $$PWD/qxsduserschematype_p.h \
+ $$PWD/qxsdvalidatedxmlnodemodel_p.h \
+ $$PWD/qxsdvalidatinginstancereader_p.h \
+ $$PWD/qxsdwildcard_p.h \
+ $$PWD/qxsdxpathexpression_p.h
+
+SOURCES += $$PWD/qnamespacesupport.cpp \
+ $$PWD/qxsdalternative.cpp \
+ $$PWD/qxsdannotated.cpp \
+ $$PWD/qxsdannotation.cpp \
+ $$PWD/qxsdapplicationinformation.cpp \
+ $$PWD/qxsdassertion.cpp \
+ $$PWD/qxsdattribute.cpp \
+ $$PWD/qxsdattributereference.cpp \
+ $$PWD/qxsdattributeterm.cpp \
+ $$PWD/qxsdattributeuse.cpp \
+ $$PWD/qxsdattributegroup.cpp \
+ $$PWD/qxsdcomplextype.cpp \
+ $$PWD/qxsddocumentation.cpp \
+ $$PWD/qxsdelement.cpp \
+ $$PWD/qxsdfacet.cpp \
+ $$PWD/qxsdidcache.cpp \
+ $$PWD/qxsdidchelper.cpp \
+ $$PWD/qxsdidentityconstraint.cpp \
+ $$PWD/qxsdinstancereader.cpp \
+ $$PWD/qxsdmodelgroup.cpp \
+ $$PWD/qxsdnotation.cpp \
+ $$PWD/qxsdparticle.cpp \
+ $$PWD/qxsdparticlechecker.cpp \
+ $$PWD/qxsdreference.cpp \
+ $$PWD/qxsdsimpletype.cpp \
+ $$PWD/qxsdschema.cpp \
+ $$PWD/qxsdschemachecker.cpp \
+ $$PWD/qxsdschemachecker_setup.cpp \
+ $$PWD/qxsdschemacontext.cpp \
+ $$PWD/qxsdschemadebugger.cpp \
+ $$PWD/qxsdschemahelper.cpp \
+ $$PWD/qxsdschemamerger.cpp \
+ $$PWD/qxsdschemaparser.cpp \
+ $$PWD/qxsdschemaparser_setup.cpp \
+ $$PWD/qxsdschemaparsercontext.cpp \
+ $$PWD/qxsdschemaresolver.cpp \
+ $$PWD/qxsdschematoken.cpp \
+ $$PWD/qxsdschematypesfactory.cpp \
+ $$PWD/qxsdstatemachinebuilder.cpp \
+ $$PWD/qxsdterm.cpp \
+ $$PWD/qxsdtypechecker.cpp \
+ $$PWD/qxsdwildcard.cpp \
+ $$PWD/qxsdvalidatedxmlnodemodel.cpp \
+ $$PWD/qxsdvalidatinginstancereader.cpp \
+ $$PWD/qxsdxpathexpression.cpp
+
+RESOURCES += $$PWD/builtinschemas.qrc
diff --git a/src/xmlpatterns/schema/schemas/xml.xsd b/src/xmlpatterns/schema/schemas/xml.xsd
new file mode 100644
index 0000000..eeb9db5
--- /dev/null
+++ b/src/xmlpatterns/schema/schemas/xml.xsd
@@ -0,0 +1,145 @@
+<?xml version='1.0'?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
+
+ <xs:annotation>
+ <xs:documentation>
+ See http://www.w3.org/XML/1998/namespace.html and
+ http://www.w3.org/TR/REC-xml for information about this namespace.
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+
+ Note that local names in this namespace are intended to be defined
+ only by the World Wide Web Consortium or its subgroups. The
+ following names are currently defined in this namespace and should
+ not be used with conflicting semantics by any Working Group,
+ specification, or document instance:
+
+ base (as an attribute name): denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.
+
+ id (as an attribute name): denotes an attribute whose value
+ should be interpreted as if declared to be of type ID.
+ This name is reserved by virtue of its definition in the
+ xml:id specification.
+
+ lang (as an attribute name): denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.
+
+ space (as an attribute name): denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.
+
+ Father (in any context at all): denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+
+ In appreciation for his vision, leadership and dedication
+ the W3C XML Plenary on this 10th day of February, 2000
+ reserves for Jon Bosak in perpetuity the XML name
+ xml:Father
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>This schema defines attributes and an attribute group
+ suitable for use by
+ schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
+ attributes on elements they define.
+
+ To enable this, such a schema must import this schema
+ for the XML namespace, e.g. as follows:
+ &lt;schema . . .>
+ . . .
+ &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+
+ Subsequently, qualified reference to any of the attributes
+ or the group defined below will have the desired effect, e.g.
+
+ &lt;type . . .>
+ . . .
+ &lt;attributeGroup ref="xml:specialAttrs"/>
+
+ will define a type which will schema-validate an instance
+ element with any of those attributes</xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+ <xs:documentation>In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+ http://www.w3.org/2007/08/xml.xsd.
+ At the date of issue it can also be found at
+ http://www.w3.org/2001/xml.xsd.
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML Schema
+ itself, or with the XML namespace itself. In other words, if the XML
+ Schema or XML namespaces change, the version of this document at
+ http://www.w3.org/2001/xml.xsd will change
+ accordingly; the version at
+ http://www.w3.org/2007/08/xml.xsd will not change.
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+ <xs:annotation>
+ <xs:documentation>Attempting to install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values is probably never
+ going to be a realistic possibility. See
+ RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
+ at http://www.iana.org/assignments/lang-tag-apps.htm for
+ further information.
+
+ The union allows for the 'un-declaration' of xml:lang with
+ the empty string.</xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:union memberTypes="xs:language">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value=""/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+ <xs:annotation>
+ <xs:documentation>See http://www.w3.org/TR/xmlbase/ for
+ information about this attribute.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="id" type="xs:ID">
+ <xs:annotation>
+ <xs:documentation>See http://www.w3.org/TR/xml-id/ for
+ information about this attribute.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ <xs:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+</xs:schema>
diff --git a/src/xmlpatterns/schema/schemas/xml.xsd-LICENSE b/src/xmlpatterns/schema/schemas/xml.xsd-LICENSE
new file mode 100644
index 0000000..2c687d8
--- /dev/null
+++ b/src/xmlpatterns/schema/schemas/xml.xsd-LICENSE
@@ -0,0 +1,40 @@
+W3CŪ SOFTWARE NOTICE AND LICENSE
+
+This license came from: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+This work (and included software, documentation such as READMEs, or other
+related items) is being provided by the copyright holders under the following
+license. By obtaining, using and/or copying this work, you (the licensee)
+agree that you have read, understood, and will comply with the following
+terms and conditions.
+
+Permission to copy, modify, and distribute this software and its
+documentation, with or without modification, for any purpose and without
+fee or royalty is hereby granted, provided that you include the following on
+ALL copies of the software and documentation or portions thereof, including
+modifications:
+
+ 1. The full text of this NOTICE in a location viewable to users of the
+ redistributed or derivative work.
+ 2. Any pre-existing intellectual property disclaimers, notices, or terms
+ and conditions. If none exist, the W3C Software Short Notice should be
+ included (hypertext is preferred, text is permitted)
+ within the body of any redistributed or derivative code.
+ 3. Notice of any changes or modifications to the files, including the date
+ changes were made. (We recommend you provide URIs to the location from
+ which the code is derived.)
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS
+MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
+PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE
+ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
+DOCUMENTATION.
+
+The name and trademarks of copyright holders may NOT be used in
+advertising or publicity pertaining to the software without specific, written
+prior permission. Title to copyright in this software and any associated
+documentation will at all times remain with copyright holders.
diff --git a/src/xmlpatterns/schema/tokens.xml b/src/xmlpatterns/schema/tokens.xml
new file mode 100644
index 0000000..b3b8e18
--- /dev/null
+++ b/src/xmlpatterns/schema/tokens.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tokenAutomaton scope="public"
+ className="XsdSchemaToken"
+ headerFile="qxsdschematoken_p.h"
+ sourceFile="qxsdschematoken.cpp"
+ defaultToken="NoKeyword"
+ tokenEnum="NodeName"
+ hasToString="true"
+ includeGuardName="QPatternist_XsdSchemaToken_h">
+ <tokens>
+ <token>abstract</token>
+ <token>all</token>
+ <token>alternative</token>
+ <token>annotation</token>
+ <token>any</token>
+ <token>anyAttribute</token>
+ <token>appinfo</token>
+ <token>appliesToEmpty</token>
+ <token>assert</token>
+ <token>assertion</token>
+ <token>attribute</token>
+ <token>attributeFormDefault</token>
+ <token>attributeGroup</token>
+ <token>base</token>
+ <token>block</token>
+ <token>blockDefault</token>
+ <token>choice</token>
+ <token>collapse</token>
+ <token>complexContent</token>
+ <token>complexType</token>
+ <token>default</token>
+ <token>defaultAttributes</token>
+ <token>defaultAttributesApply</token>
+ <token>defaultOpenContent</token>
+ <token>documentation</token>
+ <token>element</token>
+ <token>elementFormDefault</token>
+ <token>enumeration</token>
+ <token>extension</token>
+ <token>field</token>
+ <token>final</token>
+ <token>finalDefault</token>
+ <token>fixed</token>
+ <token>form</token>
+ <token>fractionDigits</token>
+ <token>group</token>
+ <token>id</token>
+ <token>import</token>
+ <token>include</token>
+ <token>itemType</token>
+ <token>key</token>
+ <token>keyref</token>
+ <token>length</token>
+ <token>list</token>
+ <token>maxExclusive</token>
+ <token>maxInclusive</token>
+ <token>maxLength</token>
+ <token>maxOccurs</token>
+ <token>memberTypes</token>
+ <token>minExclusive</token>
+ <token>minInclusive</token>
+ <token>minLength</token>
+ <token>minOccurs</token>
+ <token>mixed</token>
+ <token>mode</token>
+ <token>name</token>
+ <token>namespace</token>
+ <token>nillable</token>
+ <token>notation</token>
+ <token>notNamespace</token>
+ <token>notQName</token>
+ <token>openContent</token>
+ <token>override</token>
+ <token>preserve</token>
+ <token>pattern</token>
+ <token>processContents</token>
+ <token>public</token>
+ <token>redefine</token>
+ <token>ref</token>
+ <token>refer</token>
+ <token>replace</token>
+ <token>restriction</token>
+ <token>schema</token>
+ <token>schemaLocation</token>
+ <token>selector</token>
+ <token>sequence</token>
+ <token>simpleContent</token>
+ <token>simpleType</token>
+ <token>source</token>
+ <token>substitutionGroup</token>
+ <token>system</token>
+ <token>targetNamespace</token>
+ <token>test</token>
+ <token>totalDigits</token>
+ <token>type</token>
+ <token>union</token>
+ <token>unique</token>
+ <token>use</token>
+ <token>value</token>
+ <token>version</token>
+ <token>whiteSpace</token>
+ <token>xpath</token>
+ <token name="XPathDefaultNamespace">xpathDefaultNamespace</token>
+ <token name="XmlLanguage">xml:lang</token>
+ <token name="XML_NS_SCHEMA_URI">http://www.w3.org/2001/XMLSchema</token>
+ </tokens>
+
+ <boilerplate>
+
+ <prolog>/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+</prolog>
+
+ </boilerplate>
+
+</tokenAutomaton>