diff options
author | Peter Hartmann <peter.hartmann@nokia.com> | 2009-12-08 18:15:58 (GMT) |
---|---|---|
committer | Peter Hartmann <peter.hartmann@nokia.com> | 2010-06-14 14:48:32 (GMT) |
commit | b00cd9859d8b666b851953ee3b37def0ab078a54 (patch) | |
tree | fb3901a6e1291506a3721086ca22cfe98e28e950 /src/xmlpatterns | |
parent | ea8817a59e92e40927ae4cecd301771eb115fb6f (diff) | |
download | Qt-b00cd9859d8b666b851953ee3b37def0ab078a54.zip Qt-b00cd9859d8b666b851953ee3b37def0ab078a54.tar.gz Qt-b00cd9859d8b666b851953ee3b37def0ab078a54.tar.bz2 |
QXmlSchema: allow usage of xsd:all
previously, loading schemas that contained xsd:all elements was not
possible because the algorithm used did not scale in that case.
This patch introduces a special checking for those elements which
removes the performance downside.
Reviewed-by: Tobias Koenig <tokoe@kde.org>
Task-number: QTBUG-6485
Diffstat (limited to 'src/xmlpatterns')
-rw-r--r-- | src/xmlpatterns/schema/qxsdparticlechecker.cpp | 30 | ||||
-rw-r--r-- | src/xmlpatterns/schema/qxsdparticlechecker_p.h | 7 |
2 files changed, 37 insertions, 0 deletions
diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp index ef1d135..15c2afe 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker.cpp +++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp @@ -344,6 +344,19 @@ bool XsdParticleChecker::hasDuplicatedElements(const XsdParticle::Ptr &particle, 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 @@ bool XsdParticleChecker::isUPAConform(const XsdParticle::Ptr &particle, const Na 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) { /** diff --git a/src/xmlpatterns/schema/qxsdparticlechecker_p.h b/src/xmlpatterns/schema/qxsdparticlechecker_p.h index 742f0d0..40c525a 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker_p.h +++ b/src/xmlpatterns/schema/qxsdparticlechecker_p.h @@ -85,6 +85,13 @@ namespace QPatternist 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) */ |