src/xmlpatterns/schema/qxsdparticlechecker.cpp
changeset 33 3e2da88830cd
parent 0 1918ee327afb
--- a/src/xmlpatterns/schema/qxsdparticlechecker.cpp	Tue Jul 06 15:10:48 2010 +0300
+++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp	Wed Aug 18 10:37:55 2010 +0300
@@ -344,6 +344,19 @@
 
 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
      */
@@ -414,6 +427,23 @@
     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)
 {
     /**