Qt 4.8
Public Types | Public Functions | Private Types | Private Functions | Properties | List of all members
QPatternist::XsdValidatingInstanceReader Class Reference

The validating schema instance reader. More...

#include <qxsdvalidatinginstancereader_p.h>

Inheritance diagram for QPatternist::XsdValidatingInstanceReader:
QPatternist::XsdInstanceReader

Public Types

typedef QExplicitlySharedDataPointer< XsdValidatingInstanceReaderPtr
 
- Public Types inherited from QPatternist::XsdInstanceReader
typedef QExplicitlySharedDataPointer< XsdInstanceReaderPtr
 

Public Functions

void addSchema (const XsdSchema::Ptr &schema, const QUrl &url)
 
bool read ()
 
 XsdValidatingInstanceReader (XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context)
 
- Public Functions inherited from QPatternist::XsdInstanceReader
 XsdInstanceReader (const QAbstractXmlNodeModel *model, const XsdSchemaContext::Ptr &context)
 

Private Types

typedef QHash< QUrl, QStringListMergedSchemas
 
typedef QHashIterator< QUrl, QStringListMergedSchemasIterator
 

Private Functions

void addIdIdRefBinding (const QString &id, const NamedSchemaComponent::Ptr &binding)
 
XsdComplexType::Ptr anyType ()
 
XsdAttribute::Ptr attributeByName (const QXmlName &name) const
 
void createAndPushStateMachine (const XsdParticle::Ptr &particle)
 
QXmlQuery createXQuery (const QList< QXmlName > &namespaceBindings, const QXmlItem &contextNode, const QString &query) const
 
XsdElement::Ptr elementByName (const QXmlName &name) const
 
void error (const QString &msg) const
 
bool loadSchema (const QString &targetNamespace, const QUrl &location)
 
QString qNameAttribute (const QXmlName &attributeName)
 
bool selectNodeSets (const XsdElement::Ptr &element, const QXmlItem &currentItem, const XsdIdentityConstraint::Ptr &constraint, TargetNode::Set &targetNodeSet, TargetNode::Set &qualifiedNodeSet)
 
SchemaType::Ptr typeByName (const QXmlName &name) const
 
bool validate (bool &hasStateMachine, XsdElement::Ptr &element)
 
bool validateAttribute (const XsdAttributeUse::Ptr &declaration, const QString &value)
 
bool validateAttribute (const XsdAttribute::Ptr &declaration, const QString &value)
 
bool validateAttributeWildcard (const QXmlName &attributeName, const XsdWildcard::Ptr &wildcard)
 
bool validateElement (const XsdElement::Ptr &declaration, bool &hasStateMachine)
 
bool validateElementComplexType (const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine)
 
bool validateElementSimpleType (const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled)
 
bool validateElementType (const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine)
 
bool validateIdentityConstraint (const XsdElement::Ptr &element, const QXmlItem &currentItem)
 
bool validateKeyIdentityConstraint (const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &targetNodeSet, const TargetNode::Set &qualifiedNodeSet)
 
bool validateKeyRefIdentityConstraint (const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet)
 
bool validateUniqueIdentityConstraint (const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet)
 

Properties

XsdComplexType::Ptr m_anyType
 
QUrl m_documentUri
 
QHash< QXmlName, TargetNode::Setm_idcKeys
 
QSet< QStringm_idRefs
 
SchemaType::Ptr m_idRefsType
 
MergedSchemas m_mergedSchemas
 
XsdValidatedXmlNodeModel::Ptr m_model
 
const NamePool::Ptr m_namePool
 
QSet< QStringm_processedNamespaces
 
QSet< QStringm_processedSchemaLocations
 
XsdSchema::Ptr m_schema
 
QStack< XsdStateMachine< XsdTerm::Ptr > > m_stateMachines
 
const QXmlName m_xsiNilName
 
const QXmlName m_xsiNoNamespaceSchemaLocationName
 
const QXmlName m_xsiSchemaLocationName
 
const QXmlName m_xsiTypeName
 

Additional Inherited Members

- Protected Functions inherited from QPatternist::XsdInstanceReader
bool atEnd () const
 
QString attribute (const QXmlName &name) const
 
QXmlItem attributeItem (const QXmlName &name) const
 
QSet< QXmlNameattributeNames () const
 
QXmlName convertToQName (const QString &name) const
 
bool hasAttribute (const QXmlName &name) const
 
bool hasChildElement () const
 
bool hasChildText () const
 
bool isEndElement () const
 
bool isStartElement () const
 
QXmlItem item () const
 
QXmlName name () const
 
QVector< QXmlNamenamespaceBindings (const QXmlNodeModelIndex &index) const
 
void readNext ()
 
QSourceLocation sourceLocation () const
 
QString text () const
 
- Protected Variables inherited from QPatternist::XsdInstanceReader
XsdSchemaContext::Ptr m_context
 

Detailed Description

The validating schema instance reader.

This class reads in a xml instance document from a QAbstractXmlNodeModel and validates it against a given xml schema.

Author
Tobias Koenig tobia.nosp@m.s.ko.nosp@m.enig@.nosp@m.noki.nosp@m.a.com

Definition at line 79 of file qxsdvalidatinginstancereader_p.h.

Typedefs

◆ MergedSchemas

Definition at line 269 of file qxsdvalidatinginstancereader_p.h.

◆ MergedSchemasIterator

Definition at line 270 of file qxsdvalidatinginstancereader_p.h.

◆ Ptr

Definition at line 82 of file qxsdvalidatinginstancereader_p.h.

Constructors and Destructors

◆ XsdValidatingInstanceReader()

XsdValidatingInstanceReader::XsdValidatingInstanceReader ( XsdValidatedXmlNodeModel model,
const QUrl documentUri,
const XsdSchemaContext::Ptr context 
)

Creates a new validating instance reader that reads the data from the given model.

Parameters
modelThe model the data shall be read from.
documentUriThe uri of the document the model is from.
contextThe context that is used to report errors etc.

Definition at line 98 of file qxsdvalidatinginstancereader.cpp.

99  : XsdInstanceReader(model, context)
100  , m_model(model)
106  , m_documentUri(documentUri)
107 {
109 }
virtual NamePool::Ptr namePool() const
const QLatin1String XSI("http://www.w3.org/2001/XMLSchema-instance")
SchemaTypeFactory::Ptr schemaTypeFactory() const
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
XsdInstanceReader(const QAbstractXmlNodeModel *model, const XsdSchemaContext::Ptr &context)
QXmlName allocateQName(const QString &uri, const QString &localName, const QString &prefix=QString())
Definition: qnamepool.cpp:251
const QLatin1String WXS("http://www.w3.org/2001/XMLSchema")
virtual SchemaType::Ptr createSchemaType(const QXmlName name) const =0

Functions

◆ addIdIdRefBinding()

void XsdValidatingInstanceReader::addIdIdRefBinding ( const QString id,
const NamedSchemaComponent::Ptr binding 
)
private

Adds the ID/IDREF binding to the validated model and checks for duplicates.

Definition at line 1221 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateAttribute(), and validateElementSimpleType().

1222 {
1223  if (!m_model->idIdRefBindings(id).isEmpty()) {
1224  error(QtXmlPatterns::tr("ID value '%1' is not unique.").arg(formatKeyword(id)));
1225  return;
1226  }
1227 
1228  m_model->addIdIdRefBinding(id, binding);
1229 }
QString formatKeyword(const QString &keyword)
QSet< NamedSchemaComponent::Ptr > idIdRefBindings(const QString &id) const
void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding)

◆ addSchema()

void XsdValidatingInstanceReader::addSchema ( const XsdSchema::Ptr schema,
const QUrl url 
)

Adds a new schema to the pool of schemas that shall be used for validation. The schema is located at the given url.

Definition at line 111 of file qxsdvalidatinginstancereader.cpp.

Referenced by loadSchema(), and QXmlSchemaValidator::validate().

112 {
113  if (!m_mergedSchemas.contains(locationUrl)) {
114  m_mergedSchemas.insert(locationUrl, QStringList() << schema->targetNamespace());
115  } else {
116  QStringList &targetNamespaces = m_mergedSchemas[locationUrl];
117  if (targetNamespaces.contains(schema->targetNamespace()))
118  return;
119 
120  targetNamespaces.append(schema->targetNamespace());
121  }
122 
123  const XsdSchemaMerger merger(m_schema, schema);
124  m_schema = merger.mergedSchema();
125 /*
126  XsdSchemaDebugger dbg(m_namePool);
127  dbg.dumpSchema(m_schema);
128 */
129 }
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
A helper class that merges two schemas into one.
QString targetNamespace() const
Definition: qxsdschema.cpp:70

◆ anyType()

XsdComplexType::Ptr XsdValidatingInstanceReader::anyType ( )
private

Returns the xs:anyType that is used to build up the state machine. We need that as the BuiltinTypes::xsAnyType is not a XsdComplexType.

Definition at line 1242 of file qxsdvalidatinginstancereader.cpp.

Referenced by validate(), and validateElementComplexType().

1243 {
1244  if (m_anyType)
1245  return m_anyType;
1246 
1247  const XsdWildcard::Ptr wildcard(new XsdWildcard());
1248  wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
1249  wildcard->setProcessContents(XsdWildcard::Lax);
1250 
1251  const XsdParticle::Ptr outerParticle(new XsdParticle());
1252  outerParticle->setMinimumOccurs(1);
1253  outerParticle->setMaximumOccurs(1);
1254 
1255  const XsdParticle::Ptr innerParticle(new XsdParticle());
1256  innerParticle->setMinimumOccurs(0);
1257  innerParticle->setMaximumOccursUnbounded(true);
1258  innerParticle->setTerm(wildcard);
1259 
1260  const XsdModelGroup::Ptr outerModelGroup(new XsdModelGroup());
1261  outerModelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
1262  outerModelGroup->setParticles(XsdParticle::List() << innerParticle);
1263  outerParticle->setTerm(outerModelGroup);
1264 
1269  m_anyType->contentType()->setParticle(outerParticle);
1270  m_anyType->setAttributeWildcard(wildcard);
1271  m_anyType->setIsAbstract(false);
1272 
1273  return m_anyType;
1274 }
void setName(const QXmlName &name)
The complex type has further elements or attributes and text as content.
Represents a XSD model group object.
void setIsAbstract(bool abstract)
Represents a XSD wildcard object.
Represents a XSD complexType object.
ContentType::Ptr contentType() const
static const SchemaType::Ptr xsAnyType
Represents a XSD particle object.
void setDerivationMethod(DerivationMethod method)
void setAttributeWildcard(const XsdWildcard::Ptr &wildcard)
QExplicitlySharedDataPointer< XsdComplexType > Ptr
If the item has a uniquely determined declaration available, it must be valid with respect to that de...

◆ attributeByName()

XsdAttribute::Ptr XsdValidatingInstanceReader::attributeByName ( const QXmlName name) const
private

Returns the attribute declaration with the given name from the pool of all schemas.

Definition at line 1207 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateElementComplexType().

1208 {
1209  return m_schema->attribute(name);
1210 }
XsdAttribute::Ptr attribute(const QXmlName &name) const
Definition: qxsdschema.cpp:103

◆ createAndPushStateMachine()

void XsdValidatingInstanceReader::createAndPushStateMachine ( const XsdParticle::Ptr particle)
private

Helper method that creates a state machine for the given particle and pushes it on the state machine stack.

Definition at line 409 of file qxsdvalidatinginstancereader.cpp.

Referenced by validate(), and validateElementComplexType().

410 {
412 
414  const XsdStateMachine<XsdTerm::Ptr>::StateId endState = builder.reset();
415  const XsdStateMachine<XsdTerm::Ptr>::StateId startState = builder.buildParticle(particle, endState);
416  builder.addStartState(startState);
417 
418 /*
419  QString fileName = QString("/tmp/foo_%1.dot").arg(m_namePool->displayName(complexType->name(m_namePool)));
420  QString pngFileName = QString("/tmp/foo_%1.png").arg(m_namePool->displayName(complexType->name(m_namePool)));
421  QFile file(fileName);
422  file.open(QIODevice::WriteOnly);
423  stateMachine.outputGraph(&file, "Hello");
424  file.close();
425  ::system(QString("dot -Tpng %1 -o%2").arg(fileName).arg(pngFileName).toLatin1().data());
426 */
427 
428  stateMachine = stateMachine.toDFA();
429 
430  m_stateMachines.push(stateMachine);
431 }
A state machine used for evaluation.
QStack< XsdStateMachine< XsdTerm::Ptr > > m_stateMachines
A helper class to build up validation state machines.

◆ createXQuery()

QXmlQuery XsdValidatingInstanceReader::createXQuery ( const QList< QXmlName > &  namespaceBindings,
const QXmlItem contextNode,
const QString query 
) const
private

Creates an QXmlQuery object with the defined namespaceBindings that has the contextNode as focus and will execute query.

Definition at line 1075 of file qxsdvalidatinginstancereader.cpp.

Referenced by selectNodeSets().

1076 {
1077  // create a public name pool from our name pool
1078  QXmlNamePool namePool(m_namePool.data());
1079 
1080  // the QXmlQuery shall work with the same name pool as we do
1081  QXmlQuery query(namePool);
1082 
1083  // add additional namespace bindings
1084  QXmlQueryPrivate *queryPrivate = query.d;
1085 
1086  for (int i = 0; i < namespaceBindings.count(); ++i) {
1087  if (!namespaceBindings.at(i).prefix() == StandardPrefixes::empty)
1088  queryPrivate->addAdditionalNamespaceBinding(namespaceBindings.at(i));
1089  }
1090 
1091  // set the context node for that query and the query string
1092  query.setFocus(contextNode);
1093  query.setQuery(queryString, m_documentUri);
1094 
1095  return query;
1096 }
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
void addAdditionalNamespaceBinding(const QXmlName &binding)
Definition: qxmlquery_p.h:272
QString prefix(const QXmlNamePool &query) const
Returns the prefix.
Definition: qxmlname.cpp:370
The QXmlNamePool class is a table of shared strings referenced by instances of QXmlName.
Definition: qxmlnamepool.h:69
T * data() const
Returns a pointer to the shared data object.
Definition: qshareddata.h:145
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
Data * d
Definition: qstring.h:618
The QXmlQuery class performs XQueries on XML data, or on non-XML data modeled to look like XML...
Definition: qxmlquery.h:79

◆ elementByName()

XsdElement::Ptr XsdValidatingInstanceReader::elementByName ( const QXmlName name) const
private

Returns the element declaration with the given name from the pool of all schemas.

Definition at line 1202 of file qxsdvalidatinginstancereader.cpp.

Referenced by validate().

1203 {
1204  return m_schema->element(name);
1205 }
XsdElement::Ptr element(const QXmlName &name) const
Definition: qxsdschema.cpp:82

◆ error()

void XsdValidatingInstanceReader::error ( const QString msg) const
private

Reports an error via the report context.

Definition at line 184 of file qxsdvalidatinginstancereader.cpp.

Referenced by addIdIdRefBinding(), loadSchema(), qNameAttribute(), read(), selectNodeSets(), validate(), validateAttribute(), validateElement(), validateElementComplexType(), validateElementSimpleType(), validateElementType(), validateKeyIdentityConstraint(), validateKeyRefIdentityConstraint(), and validateUniqueIdentityConstraint().

185 {
187 }
T * data() const
Returns a pointer to the shared data object.
Definition: qshareddata.h:145
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
QSourceLocation sourceLocation() const

◆ loadSchema()

bool XsdValidatingInstanceReader::loadSchema ( const QString targetNamespace,
const QUrl location 
)
private

Loads a schema with the given targetNamespace from the given 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.

Definition at line 189 of file qxsdvalidatinginstancereader.cpp.

Referenced by validate().

190 {
193  if (!reply)
194  return true;
195 
196  // we have to create a separated schema context here, that however shares the type factory
198  context->m_schemaTypeFactory = m_context->m_schemaTypeFactory;
199 
200  QXmlSchemaPrivate schema(context);
201  schema.load(reply.data(), location, targetNamespace);
202  if (!schema.isValid()) {
203  error(QtXmlPatterns::tr("Loaded schema file is invalid."));
204  return false;
205  }
206 
207  addSchema(schema.m_schemaParserContext->schema(), location);
208 
209  return true;
210 }
virtual QNetworkAccessManager * networkAccessManager() const
void addSchema(const XsdSchema::Ptr &schema, const QUrl &url)
A context for schema parsing and validation.
A smart pointer very similar to std::auto_ptr.
Definition: qautoptr_p.h:73
SchemaTypeFactory::Ptr m_schemaTypeFactory
The resource loader will report no error and return an empty QNetworkReply.
static QNetworkReply * load(const QUrl &uri, QNetworkAccessManager *const networkManager, const ReportContext::Ptr &context, ErrorHandling handling=FailOnError)
Helper function that do NetworkAccessDelegator::get(), but does it blocked.
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63

◆ qNameAttribute()

QString XsdValidatingInstanceReader::qNameAttribute ( const QXmlName attributeName)
private

Helper method that reads an attribute of type xs:QName and does syntax checking.

Definition at line 1231 of file qxsdvalidatinginstancereader.cpp.

Referenced by validate(), and validateElement().

1232 {
1233  const QString value = attribute(attributeName).simplified();
1234  if (!XPathHelper::isQName(value)) {
1235  error(QtXmlPatterns::tr("'%1' attribute contains invalid QName content: %2.").arg(m_namePool->displayName(attributeName)).arg(formatData(value)));
1236  return QString();
1237  } else {
1238  return value;
1239  }
1240 }
QString displayName(const QXmlName qName) const
Definition: qnamepool.cpp:347
The QString class provides a Unicode character string.
Definition: qstring.h:83
static QString formatData(const QString &data)
QString attribute(const QXmlName &name) const
QString simplified() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end, and that has each sequence o...
Definition: qstring.cpp:4415
static bool isQName(const QString &qName)

◆ read()

bool XsdValidatingInstanceReader::read ( )

Reads and validates the instance document.

Definition at line 131 of file qxsdvalidatinginstancereader.cpp.

Referenced by QXmlSchemaValidator::validate().

132 {
133  while (!atEnd()) {
134  readNext();
135 
136  if (isEndElement())
137  return true;
138 
139  if (isStartElement()) {
140  const QXmlName elementName = name();
141  const QXmlItem currentItem = item();
142  bool hasStateMachine = false;
143  XsdElement::Ptr processedElement;
144 
145  if (!validate(hasStateMachine, processedElement))
146  return false;
147 
148  read();
149 
150  if (processedElement) { // for wildcard with 'skip' we have no element
151  m_model->setAssignedElement(currentItem.toNodeModelIndex(), processedElement);
152 
153  // check identity constraints after all child nodes have been
154  // validated, so that we know there assigned types
155  validateIdentityConstraint(processedElement, currentItem);
156  }
157 
158  if (!m_stateMachines.isEmpty() && hasStateMachine) {
159  if (!m_stateMachines.top().inEndState()) {
160  error(QtXmlPatterns::tr("Element %1 is missing child element.").arg(formatKeyword(m_namePool->displayName(elementName))));
161  return false;
162  }
163  m_stateMachines.pop();
164  }
165  }
166  }
167 
168  // final validations
169 
170  // check IDREF occurrences
171  const QStringList ids = m_model->idIdRefBindingIds();
172  QSetIterator<QString> it(m_idRefs);
173  while (it.hasNext()) {
174  const QString id = it.next();
175  if (!ids.contains(id)) {
176  error(QtXmlPatterns::tr("There is one IDREF value with no corresponding ID: %1.").arg(formatKeyword(id)));
177  return false;
178  }
179  }
180 
181  return true;
182 }
bool validateIdentityConstraint(const XsdElement::Ptr &element, const QXmlItem &currentItem)
QString displayName(const QXmlName qName) const
Definition: qnamepool.cpp:347
QString formatKeyword(const QString &keyword)
#define it(className, varName)
The QXmlItem class contains either an XML node or an atomic value.
The QString class provides a Unicode character string.
Definition: qstring.h:83
void setAssignedElement(const QXmlNodeModelIndex &index, const XsdElement::Ptr &element)
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
bool validate(bool &hasStateMachine, XsdElement::Ptr &element)
QStack< XsdStateMachine< XsdTerm::Ptr > > m_stateMachines
QXmlNodeModelIndex toNodeModelIndex() const
If this QXmlItem represents a node, it returns the item as a QXmlNodeModelIndex.

◆ selectNodeSets()

bool XsdValidatingInstanceReader::selectNodeSets ( const XsdElement::Ptr element,
const QXmlItem currentItem,
const XsdIdentityConstraint::Ptr constraint,
TargetNode::Set targetNodeSet,
TargetNode::Set qualifiedNodeSet 
)
private

Selects two sets of nodes that match the given identity constraint.

Parameters
elementThe element the identity constraint belongs to.
currentItemThe current element that will be used as focus for the XQuery.
constraintThe constraint (selector and fields) that describe the two sets.
targetNodeSetThe target node set as defined by the schema specification.
qualifiedNodeSetThe qualified node set as defined by the schema specification.

Definition at line 1098 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateIdentityConstraint().

1099 {
1100  // at first select all target nodes
1101  const XsdXPathExpression::Ptr selector = constraint->selector();
1102  const XsdXPathExpression::List fields = constraint->fields();
1103 
1104  QXmlQuery query = createXQuery(selector->namespaceBindings(), currentItem, selector->expression());
1105 
1106  QXmlResultItems resultItems;
1107  query.evaluateTo(&resultItems);
1108 
1109  // now we iterate over all target nodes and select the fields for each node
1110  QXmlItem item(resultItems.next());
1111  while (!item.isNull()) {
1112 
1113  TargetNode targetNode(item);
1114 
1115  for (int i = 0; i < fields.count(); ++i) {
1116  const XsdXPathExpression::Ptr field = fields.at(i);
1117  QXmlQuery fieldQuery = createXQuery(field->namespaceBindings(), item, field->expression());
1118 
1119  QXmlResultItems fieldResultItems;
1120  fieldQuery.evaluateTo(&fieldResultItems);
1121 
1122  // copy result into vetor for better testing...
1123  QVector<QXmlItem> fieldVector;
1124  QXmlItem fieldItem(fieldResultItems.next());
1125  while (!fieldItem.isNull()) {
1126  fieldVector.append(fieldItem);
1127  fieldItem = fieldResultItems.next();
1128  }
1129 
1130  if (fieldVector.count() > 1) {
1131  error(QtXmlPatterns::tr("More than one value found for field %1.").arg(formatData(field->expression())));
1132  return false;
1133  }
1134 
1135  if (fieldVector.count() == 1) {
1136  fieldItem = fieldVector.first();
1137 
1138  const QXmlNodeModelIndex index = fieldItem.toNodeModelIndex();
1139  const SchemaType::Ptr type = m_model->assignedType(index);
1140 
1141  bool typeOk = true;
1142  if (type->isComplexType()) {
1143  if (type->isDefinedBySchema()) {
1145  typeOk = false;
1146  } else {
1147  typeOk = false;
1148  }
1149  }
1150  if (!typeOk) {
1151  error(QtXmlPatterns::tr("Field %1 has no simple type.").arg(formatData(field->expression())));
1152  return false;
1153  }
1154 
1155  SchemaType::Ptr targetType = type;
1156  QString value = m_model->stringValue(fieldItem.toNodeModelIndex());
1157 
1158  if (type->isDefinedBySchema()) {
1159  if (type->isSimpleType())
1160  targetType = XsdSimpleType::Ptr(type)->primitiveType();
1161  else
1162  targetType = XsdComplexType::Ptr(type)->contentType()->simpleType();
1163  } else {
1165  targetType = BuiltinTypes::xsString;
1166  value = QLatin1String("___anySimpleType_value");
1167  }
1168  }
1169 
1170  // if it is xs:QName derived type, we normalize the name content
1171  // and do a string comparison
1173  targetType = BuiltinTypes::xsString;
1174 
1175  const QXmlName qName = convertToQName(value.trimmed());
1177  }
1178 
1179  targetNode.addField(fieldItem, value, targetType);
1180  } else {
1181  // we add an empty entry here, that makes comparison easier later on
1182  targetNode.addField(QXmlItem(), QString(), SchemaType::Ptr());
1183  }
1184  }
1185 
1186  targetNodeSet.insert(targetNode);
1187 
1188  item = resultItems.next();
1189  }
1190 
1191  // copy all items from target node set to qualified node set, that have no empty fields
1192  QSetIterator<TargetNode> it(targetNodeSet);
1193  while (it.hasNext()) {
1194  const TargetNode node = it.next();
1195  if (node.emptyFieldsCount() == 0)
1196  qualifiedNodeSet.insert(node);
1197  }
1198 
1199  return true;
1200 }
const QString & stringForLocalName(const QXmlName::LocalNameCode code) const
Definition: qnamepool_p.h:168
void evaluateTo(QXmlResultItems *result) const
Starts the evaluation and makes it available in result.
Definition: qxmlquery.cpp:815
The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeM...
int type
Definition: qmetatype.cpp:239
QList< QXmlName > namespaceBindings() const
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
#define it(className, varName)
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
T & first()
Returns a reference to the first item in the vector.
Definition: qvector.h:260
The QXmlResultItems class iterates through the results of evaluating an XQuery in QXmlQuery...
The QXmlItem class contains either an XML node or an atomic value.
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
A helper class for validating identity constraints.
QXmlName convertToQName(const QString &name) const
ContentType::Ptr contentType() const
static const AtomicType::Ptr xsString
SchemaType::Ptr assignedType(const QXmlNodeModelIndex &index) const
QString trimmed() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end.
Definition: qstring.cpp:4506
QXmlQuery createXQuery(const QList< QXmlName > &namespaceBindings, const QXmlItem &contextNode, const QString &query) const
XsdXPathExpression::List fields() const
virtual bool isComplexType() const
Definition: qschematype.cpp:70
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
void append(const T &t)
Inserts value at the end of the vector.
Definition: qvector.h:573
const_iterator insert(const T &value)
Definition: qset.h:179
static QString formatData(const QString &data)
XsdXPathExpression::Ptr selector() const
QString localName(const QXmlNamePool &query) const
Returns the local name.
Definition: qxmlname.cpp:387
The complex type has only simple type content (e.g. text, number etc.)
NamespaceCode namespaceURI() const
Definition: qnamepool_p.h:503
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
static const AtomicType::Ptr xsQName
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
static const SchemaType::Ptr xsAnySimpleType
const QString & stringForNamespace(const QXmlName::NamespaceCode code) const
Definition: qnamepool_p.h:180
AnySimpleType::Ptr primitiveType() const
quint16 index
QExplicitlySharedDataPointer< XsdComplexType > Ptr
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
virtual QXmlName name(const NamePool::Ptr &np) const =0
Returns the name of the type.
The QXmlQuery class performs XQueries on XML data, or on non-XML data modeled to look like XML...
Definition: qxmlquery.h:79
virtual QString stringValue(const QXmlNodeModelIndex &n) const
Returns the string value for node n.
bool isNull() const
Returns true if this QXmlItem is neither a node nor an atomic value.

◆ typeByName()

SchemaType::Ptr XsdValidatingInstanceReader::typeByName ( const QXmlName name) const
private

Returns the type declaration with the given name from the pool of all schemas.

Definition at line 1212 of file qxsdvalidatinginstancereader.cpp.

Referenced by validate(), and validateElement().

1213 {
1214  const SchemaType::Ptr type = m_schema->type(name);
1215  if (type)
1216  return type;
1217 
1218  return m_context->schemaTypeFactory()->createSchemaType(name);
1219 }
int type
Definition: qmetatype.cpp:239
SchemaTypeFactory::Ptr schemaTypeFactory() const
SchemaType::Ptr type(const QXmlName &name) const
Definition: qxsdschema.cpp:124
virtual SchemaType::Ptr createSchemaType(const QXmlName name) const =0

◆ validate()

bool XsdValidatingInstanceReader::validate ( bool &  hasStateMachine,
XsdElement::Ptr element 
)
private

Validates the current element tag of the instance document.

Parameters
hasStateMachineUsed to remember whether this element represents the start tag of a complex type and therefor pushes a new state machine on the stack.
elementUsed to remember which element has been validated in this step.

Definition at line 212 of file qxsdvalidatinginstancereader.cpp.

Referenced by read().

213 {
214  // first check if a custom schema is defined
216  const QString schemaLocation = attribute(m_xsiSchemaLocationName);
217  const QStringList parts = schemaLocation.split(QLatin1Char(' '), QString::SkipEmptyParts);
218  if ((parts.count()%2) == 1) {
219  error(QtXmlPatterns::tr("%1 contains invalid data.").arg(formatKeyword(m_namePool, m_xsiSchemaLocationName)));
220  return false;
221  }
222 
223  for (int i = 0; i < parts.count(); i += 2) {
224  const QString identifier = QString::fromLatin1("%1 %2").arg(parts.at(i)).arg(parts.at(i + 1));
225  if (m_processedSchemaLocations.contains(identifier))
226  continue;
227  else
229 
230  // check constraint 4) from http://www.w3.org/TR/xmlschema-1/#schema-loc (only valid for XML Schema 1.0?)
231  if (m_processedNamespaces.contains(parts.at(i))) {
232  error(QtXmlPatterns::tr("xsi:schemaLocation namespace %1 has already appeared earlier in the instance document.").arg(formatKeyword(parts.at(i))));
233  return false;
234  }
235 
236  QUrl url(parts.at(i + 1));
237  if (url.isRelative()) {
239 
240  url = m_documentUri.resolved(url);
241  }
242 
243  loadSchema(parts.at(i), url);
244  }
245  }
246 
248  const QString schemaLocation = attribute(m_xsiNoNamespaceSchemaLocationName);
249 
250  if (!m_processedSchemaLocations.contains(schemaLocation)) {
251  m_processedSchemaLocations.insert(schemaLocation);
252 
254  error(QtXmlPatterns::tr("xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute."));
255  return false;
256  }
257 
258  QUrl url(schemaLocation);
259  if (url.isRelative()) {
261 
262  url = m_documentUri.resolved(url);
263  }
264 
265  loadSchema(QString(), url);
266  }
267  }
268 
270 
271  if (!m_schema) {
272  error(QtXmlPatterns::tr("No schema defined for validation."));
273  return false;
274  }
275 
276  // check if we are 'inside' a type definition
277  if (m_stateMachines.isEmpty()) {
278  // find out the type of the top-level element
279  XsdElement::Ptr element = elementByName(name());
280  if (!element) {
281  if (!hasAttribute(m_xsiTypeName)) {
282  error(QtXmlPatterns::tr("No definition for element %1 available.").arg(formatKeyword(m_namePool, name())));
283  return false;
284  }
285 
286  // This instance document has an element with no definition in the schema
287  // but an explicitly given type, that is fine according to the spec.
288  // We will create an element definition manually here and continue the
289  // normal validation process
290  element = XsdElement::Ptr(new XsdElement());
291  element->setName(name());
292  element->setIsAbstract(false);
294 
296  const QXmlName typeName = convertToQName(type);
297 
298  const SchemaType::Ptr elementType = typeByName(typeName);
299  if (!elementType) {
300  error(QtXmlPatterns::tr("Specified type %1 is not known to the schema.").arg(formatType(m_namePool, typeName)));
301  return false;
302  }
303  element->setType(elementType);
304  }
305 
306  // rememeber the element we process
307  processedElement = element;
308 
309  if (!validateElement(element, hasStateMachine)) {
310  return false;
311  }
312 
313  } else {
314  if (!m_stateMachines.top().proceed<QXmlName>(name())) {
315  error(QtXmlPatterns::tr("Element %1 is not defined in this scope.").arg(formatKeyword(m_namePool, name())));
316  return false;
317  }
318 
319  const XsdTerm::Ptr term = m_stateMachines.top().lastTransition();
320  if (term->isElement()) {
321  const XsdElement::Ptr element(term);
322 
323  // rememeber the element we process
324  processedElement = element;
325 
326  if (!validateElement(element, hasStateMachine))
327  return false;
328 
329  } else {
330  const XsdWildcard::Ptr wildcard(term);
331  if (wildcard->processContents() != XsdWildcard::Skip) {
332  XsdElement::Ptr elementDeclaration = elementByName(name());
333  if (!elementDeclaration) {
335  // This instance document has an element with no definition in the schema
336  // but an explicitly given type, that is fine according to the spec.
337  // We will create an element definition manually here and continue the
338  // normal validation process
339  elementDeclaration = XsdElement::Ptr(new XsdElement());
340  elementDeclaration->setName(name());
341  elementDeclaration->setIsAbstract(false);
342  elementDeclaration->setIsNillable(hasAttribute(m_xsiNilName));
343 
344  const QString type = qNameAttribute(m_xsiTypeName);
345  const QXmlName typeName = convertToQName(type);
346 
347  const SchemaType::Ptr elementType = typeByName(typeName);
348  if (!elementType) {
349  error(QtXmlPatterns::tr("Specified type %1 is not known to the schema.").arg(formatType(m_namePool, typeName)));
350  return false;
351  }
352  elementDeclaration->setType(elementType);
353  }
354  }
355 
356  if (!elementDeclaration) {
357  if (wildcard->processContents() == XsdWildcard::Strict) {
358  error(QtXmlPatterns::tr("Declaration for element %1 does not exist.").arg(formatKeyword(m_namePool->displayName(name()))));
359  return false;
360  } else {
361  // in this case we put a state machine for the xs:anyType on the statemachine stack,
362  // so we accept every content of this element
363 
364  createAndPushStateMachine(anyType()->contentType()->particle());
365  hasStateMachine = true;
366  }
367  } else {
368  if (!validateElement(elementDeclaration, hasStateMachine)) {
369  if (wildcard->processContents() == XsdWildcard::Strict) {
370  error(QtXmlPatterns::tr("Element %1 contains invalid content.").arg(formatKeyword(m_namePool->displayName(name()))));
371  return false;
372  }
373  }
374 
375  // rememeber the type of that element node
376  m_model->setAssignedType(item().toNodeModelIndex(), elementDeclaration->type());
377  }
378  } else { // wildcard process contents type is Skip
379  // in this case we put a state machine for the xs:anyType on the statemachine stack,
380  // so we accept every content of this element
381 
382  const XsdWildcard::Ptr wildcard(new XsdWildcard());
383  wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any);
384  wildcard->setProcessContents(XsdWildcard::Skip);
385 
386  const XsdParticle::Ptr outerParticle(new XsdParticle());
387  outerParticle->setMinimumOccurs(1);
388  outerParticle->setMaximumOccurs(1);
389 
390  const XsdParticle::Ptr innerParticle(new XsdParticle());
391  innerParticle->setMinimumOccurs(0);
392  innerParticle->setMaximumOccursUnbounded(true);
393  innerParticle->setTerm(wildcard);
394 
395  const XsdModelGroup::Ptr outerModelGroup(new XsdModelGroup());
396  outerModelGroup->setCompositor(XsdModelGroup::SequenceCompositor);
397  outerModelGroup->setParticles(XsdParticle::List() << innerParticle);
398  outerParticle->setTerm(outerModelGroup);
399 
400  createAndPushStateMachine(outerParticle);
401  hasStateMachine = true;
402  }
403  }
404  }
405 
406  return true;
407 }
QString displayName(const QXmlName qName) const
Definition: qnamepool.cpp:347
QString qNameAttribute(const QXmlName &attributeName)
int type
Definition: qmetatype.cpp:239
bool isValid() const
Returns true if the URL is valid; otherwise returns false.
Definition: qurl.cpp:4303
Represents a XSD element object.
Definition: qxsdelement_p.h:83
void setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type)
Represents a XSD model group object.
QString formatKeyword(const QString &keyword)
bool loadSchema(const QString &targetNamespace, const QUrl &location)
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
Represents a XSD wildcard object.
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
SchemaType::Ptr typeByName(const QXmlName &name) const
bool validateElement(const XsdElement::Ptr &declaration, bool &hasStateMachine)
QXmlName convertToQName(const QString &name) const
SchemaType::Ptr type() const
virtual bool isElement() const
Definition: qxsdterm.cpp:48
No constraints at all: the item must simply be well-formed XML.
There must be a top-level declaration for the item available, or the item must have an xsi:type...
const char * typeName
Definition: qmetatype.cpp:239
bool contains(const T &value) const
Definition: qset.h:91
Represents a XSD particle object.
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
const_iterator insert(const T &value)
Definition: qset.h:179
void setIsAbstract(bool abstract)
void setType(const SchemaType::Ptr &type)
QString attribute(const QXmlName &name) const
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
void setIsNillable(bool nillable)
XsdElement::Ptr elementByName(const QXmlName &name) const
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
bool hasAttribute(const QXmlName &name) const
const QString & stringForNamespace(const QXmlName::NamespaceCode code) const
Definition: qnamepool_p.h:180
QExplicitlySharedDataPointer< XsdElement > Ptr
Definition: qxsdelement_p.h:86
QStack< XsdStateMachine< XsdTerm::Ptr > > m_stateMachines
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
QUrl resolved(const QUrl &relative) const
Returns the result of the merge of this URL with relative.
Definition: qurl.cpp:5819
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
void createAndPushStateMachine(const XsdParticle::Ptr &particle)

◆ validateAttribute() [1/2]

bool XsdValidatingInstanceReader::validateAttribute ( const XsdAttributeUse::Ptr declaration,
const QString value 
)
private

Validates the given value against the attribute use declaration.

Definition at line 833 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateElementComplexType().

834 {
835  const AnySimpleType::Ptr attributeType = declaration->attribute()->type();
836  const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(attributeType, m_context);
837 
838  const QString actualValue = XsdTypeChecker::normalizedValue(value, facets);
839 
840  QString errorMsg;
841  AnySimpleType::Ptr boundType;
842 
843  const QXmlNodeModelIndex index = attributeItem(declaration->attribute()->name(m_namePool)).toNodeModelIndex();
844 
845  const XsdTypeChecker checker(m_context, namespaceBindings(index), sourceLocation());
846  if (!checker.isValidString(actualValue, attributeType, errorMsg, &boundType)) {
847  error(QtXmlPatterns::tr("Content of attribute %1 does not match its type definition: %2.").arg(formatKeyword(declaration->attribute()->displayName(m_namePool))).arg(errorMsg));
848  return false;
849  }
850 
851  // @see http://www.w3.org/TR/xmlschema11-1/#cvc-au
852  if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) {
853  const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
854  if (!checker.valuesAreEqual(actualValue, actualConstraintValue, attributeType)) {
855  error(QtXmlPatterns::tr("Content of attribute %1 does not match defined value constraint.").arg(formatKeyword(declaration->attribute()->displayName(m_namePool))));
856  return false;
857  }
858  }
859 
860  if (BuiltinTypes::xsID->wxsTypeMatches(declaration->attribute()->type())) {
861  addIdIdRefBinding(actualValue, declaration->attribute());
862  }
863 
864  if (m_idRefsType->wxsTypeMatches(declaration->attribute()->type())) {
865  const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
866  for (int i = 0; i < idRefs.count(); ++i)
867  m_idRefs.insert(idRefs.at(i));
868  } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(declaration->attribute()->type())) {
869  m_idRefs.insert(actualValue);
870  }
871 
872  m_model->setAssignedType(index, declaration->attribute()->type());
873  m_model->setAssignedAttribute(index, declaration->attribute());
874 
875  return true;
876 }
static const AtomicType::Ptr xsID
The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeM...
void setAssignedAttribute(const QXmlNodeModelIndex &index, const XsdAttribute::Ptr &attribute)
void setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type)
void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding)
QString formatKeyword(const QString &keyword)
The attribute use has a fixed value set.
QXmlItem attributeItem(const QXmlName &name) const
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
virtual bool wxsTypeMatches(const SchemaType::Ptr &other) const =0
static const AtomicType::Ptr xsIDREF
static XsdFacet::Hash mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context)
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
const_iterator insert(const T &value)
Definition: qset.h:179
static QString normalizedValue(const QString &value, const XsdFacet::Hash &facets)
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)
QSourceLocation sourceLocation() const
quint16 index
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
The class that provides methods for checking a string against a type.
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QVector< QXmlName > namespaceBindings(const QXmlNodeModelIndex &index) const

◆ validateAttribute() [2/2]

bool XsdValidatingInstanceReader::validateAttribute ( const XsdAttribute::Ptr declaration,
const QString value 
)
private

Validates the given value against the attribute declaration.

Definition at line 879 of file qxsdvalidatinginstancereader.cpp.

880 {
881  const AnySimpleType::Ptr attributeType = declaration->type();
882  const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(attributeType, m_context);
883 
884  const QString actualValue = XsdTypeChecker::normalizedValue(value, facets);
885 
886  QString errorMsg;
887  AnySimpleType::Ptr boundType;
888 
889  const QXmlNodeModelIndex index = attributeItem(declaration->name(m_namePool)).toNodeModelIndex();
890 
891  const XsdTypeChecker checker(m_context, namespaceBindings(index), sourceLocation());
892  if (!checker.isValidString(actualValue, attributeType, errorMsg, &boundType)) {
893  error(QtXmlPatterns::tr("Content of attribute %1 does not match its type definition: %2.").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg));
894  return false;
895  }
896 
897  // @see http://www.w3.org/TR/xmlschema11-1/#cvc-au
898  if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Fixed) {
899  const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
900  if (!checker.valuesAreEqual(actualValue, actualConstraintValue, attributeType)) {
901  error(QtXmlPatterns::tr("Content of attribute %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
902  return false;
903  }
904  }
905 
906  if (BuiltinTypes::xsID->wxsTypeMatches(declaration->type())) {
907  addIdIdRefBinding(actualValue, declaration);
908  }
909 
910  if (m_idRefsType->wxsTypeMatches(declaration->type())) {
911  const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
912  for (int i = 0; i < idRefs.count(); ++i)
913  m_idRefs.insert(idRefs.at(i));
914  } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(declaration->type())) {
915  m_idRefs.insert(actualValue);
916  }
917 
918  m_model->setAssignedType(index, declaration->type());
919  m_model->setAssignedAttribute(index, declaration);
920 
921  return true;
922 }
static const AtomicType::Ptr xsID
The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeM...
void setAssignedAttribute(const QXmlNodeModelIndex &index, const XsdAttribute::Ptr &attribute)
void setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type)
void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding)
QString formatKeyword(const QString &keyword)
QXmlItem attributeItem(const QXmlName &name) const
ValueConstraint::Ptr valueConstraint() const
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
virtual bool wxsTypeMatches(const SchemaType::Ptr &other) const =0
static const AtomicType::Ptr xsIDREF
static XsdFacet::Hash mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context)
AnySimpleType::Ptr type() const
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
virtual QString displayName(const NamePool::Ptr &namePool) const
const_iterator insert(const T &value)
Definition: qset.h:179
static QString normalizedValue(const QString &value, const XsdFacet::Hash &facets)
virtual QXmlName name(const NamePool::Ptr &namePool) const
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)
QSourceLocation sourceLocation() const
quint16 index
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
The attribute has a fixed value set.
The class that provides methods for checking a string against a type.
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QVector< QXmlName > namespaceBindings(const QXmlNodeModelIndex &index) const

◆ validateAttributeWildcard()

bool XsdValidatingInstanceReader::validateAttributeWildcard ( const QXmlName attributeName,
const XsdWildcard::Ptr wildcard 
)
private

Validates the given attributeName against the wildcard.

Definition at line 924 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateElementComplexType().

925 {
926  // @see http://www.w3.org/TR/xmlschema11-1/#cvc-wildcard
927 
928  // wildcards using XsdWildcard::absentNamespace, so we have to fix that here
929  QXmlName name(attributeName);
932  }
933 
935 }
static QString absentNamespace()
QXmlName::NamespaceCode allocateNamespace(const QString &uri)
Definition: qnamepool_p.h:202
NamespaceCode namespaceURI() const
Definition: qnamepool_p.h:503
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
static bool wildcardAllowsExpandedName(const QXmlName &name, const XsdWildcard::Ptr &wildcard, const NamePool::Ptr &namePool)
void setNamespaceURI(const NamespaceCode c)
Definition: qnamepool_p.h:518

◆ validateElement()

bool XsdValidatingInstanceReader::validateElement ( const XsdElement::Ptr declaration,
bool &  hasStateMachine 
)
private

Validates the current tag of the instance document against the given element declaration.

Parameters
declarationThe element declaration to validate against.
hasStateMachineUsed to remember whether this element represents the start tag of a complex type and therefor pushes a new state machine on the stack.

Definition at line 433 of file qxsdvalidatinginstancereader.cpp.

Referenced by validate().

434 {
435  // http://www.w3.org/TR/xmlschema11-1/#d0e10998
436 
437  bool isNilled = false;
438 
439  // 1 tested already, 'declaration' corresponds D
440 
441  // 2
442  if (declaration->isAbstract()) {
443  error(QtXmlPatterns::tr("Element %1 is declared as abstract.").arg(formatKeyword(declaration->displayName(m_namePool))));
444  return false;
445  }
446 
447  // 3
448  if (!declaration->isNillable()) {
449  if (hasAttribute(m_xsiNilName)) {
450  error(QtXmlPatterns::tr("Element %1 is not nillable.").arg(formatKeyword(declaration->displayName(m_namePool))));
451  return false; // 3.1
452  }
453  } else {
454  if (hasAttribute(m_xsiNilName)) {
455  const QString value = attribute(m_xsiNilName);
456  const Boolean::Ptr nil = Boolean::fromLexical(value);
457  if (nil->hasError()) {
458  error(QtXmlPatterns::tr("Attribute %1 contains invalid data: %2").arg(formatKeyword(QLatin1String("nil."))).arg(formatData(value)));
459  return false;
460  }
461 
462  // 3.2.3
463  if (nil->as<Boolean>()->value() == true) {
464  // 3.2.3.1
465  if (hasChildElement() || hasChildText()) {
466  error(QtXmlPatterns::tr("Element contains content although it is nillable."));
467  return false;
468  }
469 
470  // 3.2.3.2
471  if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
472  error(QtXmlPatterns::tr("Fixed value constraint not allowed if element is nillable."));
473  return false;
474  }
475  }
476 
477  isNilled = nil->as<Boolean>()->value();
478  }
479  }
480 
481  SchemaType::Ptr finalElementType = declaration->type();
482 
483  // 4
486  const QXmlName typeName = convertToQName(type);
487 
488  const SchemaType::Ptr elementType = typeByName(typeName);
489  // 4.1
490  if (!elementType) {
491  error(QtXmlPatterns::tr("Specified type %1 is not known to the schema.").arg(formatType(m_namePool, typeName)));
492  return false;
493  }
494 
495  // 4.2
496  SchemaType::DerivationConstraints constraints = 0;
498  constraints |= SchemaType::ExtensionConstraint;
500  constraints |= SchemaType::RestrictionConstraint;
501 
502  if (!XsdSchemaHelper::isValidlySubstitutable(elementType, declaration->type(), constraints)) {
503  if (declaration->type()->name(m_namePool) != BuiltinTypes::xsAnyType->name(m_namePool)) { // xs:anyType is a valid substitutable type here
504  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())));
505  return false;
506  }
507  }
508 
509  finalElementType = elementType;
510  }
511 
512  if (!validateElementType(declaration, finalElementType, isNilled, hasStateMachine))
513  return false;
514 
515  return true;
516 }
QString qNameAttribute(const QXmlName &attributeName)
int type
Definition: qmetatype.cpp:239
bool validateElementType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine)
QString formatKeyword(const QString &keyword)
virtual bool hasError() const
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
The QString class provides a Unicode character string.
Definition: qstring.h:83
SchemaType::Ptr typeByName(const QXmlName &name) const
QXmlName convertToQName(const QString &name) const
SchemaType::Ptr type() const
static const SchemaType::Ptr xsAnyType
static AtomicValue::Ptr fromLexical(const QString &val)
Definition: qboolean.cpp:120
const TCastTarget * as() const
const char * typeName
Definition: qmetatype.cpp:239
virtual QString displayName(const NamePool::Ptr &namePool) const
The element has a fixed value set.
bool value() const
Definition: qboolean_p.h:109
static QString formatData(const QString &data)
Implements the value instance of the xs:boolean type.
Definition: qboolean_p.h:69
QString attribute(const QXmlName &name) const
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
bool hasAttribute(const QXmlName &name) const
ValueConstraint::Ptr valueConstraint() const
BlockingConstraints disallowedSubstitutions() const
static bool isValidlySubstitutable(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, const SchemaType::DerivationConstraints &constraints)
virtual QXmlName name(const NamePool::Ptr &np) const =0
Returns the name of the type.

◆ validateElementComplexType()

bool XsdValidatingInstanceReader::validateElementComplexType ( const XsdElement::Ptr declaration,
const SchemaType::Ptr type,
bool  isNilled,
bool &  hasStateMachine 
)
private

Validates the current tag of the instance document against the given complex type of the element declaration.

Parameters
declarationThe element declaration to validate against.
typeThe type to validate against.
isNilledDefines whether the element is nilled by the instance document.
hasStateMachineUsed 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 type can differ from the element declaration type if the instance document has defined it via xsi:type attribute.

Definition at line 624 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateElementType().

625 {
626  // @see http://www.w3.org/TR/xmlschema11-1/#cvc-complex-type
627 
628  // 1
629  if (!isNilled) {
630  XsdComplexType::Ptr complexType;
631 
632  if (type->isDefinedBySchema()) {
633  complexType = XsdComplexType::Ptr(type);
634  } else {
636  complexType = anyType();
637  }
638 
639  if (complexType) {
640  // 1.1
641  if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty) {
642  if (hasChildText() || hasChildElement()) {
643  error(QtXmlPatterns::tr("Element %1 contains not allowed child content.").arg(formatKeyword(declaration->displayName(m_namePool))));
644  return false;
645  }
646  }
647 
648  // 1.2
649  if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) {
650  if (hasChildElement()) {
651  error(QtXmlPatterns::tr("Element %1 contains not allowed child element.").arg(formatKeyword(declaration->displayName(m_namePool))));
652  return false;
653  }
654 
655  const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(complexType->contentType()->simpleType(), m_context);
656  QString actualValue;
657  if (hasChildText()) {
658  actualValue = XsdTypeChecker::normalizedValue(text(), facets);
659  } else {
660  if (declaration->valueConstraint())
661  actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
662  }
663 
664  QString errorMsg;
665  AnySimpleType::Ptr boundType;
666  const XsdTypeChecker checker(m_context, namespaceBindings(item().toNodeModelIndex()), sourceLocation());
667  if (!checker.isValidString(actualValue, complexType->contentType()->simpleType(), errorMsg, &boundType)) {
668  error(QtXmlPatterns::tr("Content of element %1 does not match its type definition: %2.").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg));
669  return false;
670  }
671 
672  // additional check
673  if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
674  if (!checker.valuesAreEqual(actualValue, declaration->valueConstraint()->value(), boundType)) {
675  error(QtXmlPatterns::tr("Content of element %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
676  return false;
677  }
678  }
679  }
680 
681  // 1.3
682  if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) {
683  if (!text().simplified().isEmpty()) {
684  error(QtXmlPatterns::tr("Element %1 contains not allowed text content.").arg(formatKeyword(declaration->displayName(m_namePool))));
685  return false;
686  }
687  }
688 
689  // 1.4
690  if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly ||
691  complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
692 
693  if (complexType->contentType()->particle()) {
694  createAndPushStateMachine(complexType->contentType()->particle());
695  hasStateMachine = true;
696  }
697 
698  // additional check
699  if (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) {
700  if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
701  if (hasChildElement()) {
702  error(QtXmlPatterns::tr("Element %1 cannot contain other elements, as it has fixed content.").arg(formatKeyword(declaration->displayName(m_namePool))));
703  return false;
704  }
705 
706  const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(complexType->contentType()->simpleType(), m_context);
707  QString actualValue;
708  if (hasChildText()) {
709  actualValue = XsdTypeChecker::normalizedValue(text(), facets);
710  } else {
711  if (declaration->valueConstraint())
712  actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
713  }
714 
715  if (actualValue != declaration->valueConstraint()->value()) {
716  error(QtXmlPatterns::tr("Content of element %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
717  return false;
718  }
719  }
720  }
721  }
722  }
723  }
724 
725  if (type->isDefinedBySchema()) {
726  const XsdComplexType::Ptr complexType(type);
727 
728  // create a lookup hash for faster access
729  QHash<QXmlName, XsdAttributeUse::Ptr> attributeUseHash;
730  {
731  const XsdAttributeUse::List attributeUses = complexType->attributeUses();
732  for (int i = 0; i < attributeUses.count(); ++i)
733  attributeUseHash.insert(attributeUses.at(i)->attribute()->name(m_namePool), attributeUses.at(i));
734  }
735 
736  const QSet<QXmlName> attributes(attributeNames());
737 
738  // 3
739  QHashIterator<QXmlName, XsdAttributeUse::Ptr> usesIt(attributeUseHash);
740  while (usesIt.hasNext()) {
741  usesIt.next();
742 
743  if (usesIt.value()->isRequired()) {
744  if (!attributes.contains(usesIt.key())) {
745  error(QtXmlPatterns::tr("Element %1 is missing required attribute %2.").arg(formatKeyword(declaration->displayName(m_namePool)))
746  .arg(formatKeyword(m_namePool->displayName(usesIt.key()))));
747  return false;
748  }
749  }
750  }
751 
752  bool hasIDAttribute = hasIDAttributeUse(complexType->attributeUses());
753 
754  // 2
755  QSetIterator<QXmlName> it(attributes);
756  while (it.hasNext()) {
757  const QXmlName attributeName = it.next();
758 
759  // skip builtin attributes
760  if (attributeName == m_xsiNilName ||
761  attributeName == m_xsiTypeName ||
762  attributeName == m_xsiSchemaLocationName ||
763  attributeName == m_xsiNoNamespaceSchemaLocationName)
764  continue;
765 
766  // 2.1
767  if (attributeUseHash.contains(attributeName) && (attributeUseHash.value(attributeName)->useType() != XsdAttributeUse::ProhibitedUse)) {
768  if (!validateAttribute(attributeUseHash.value(attributeName), attribute(attributeName)))
769  return false;
770  } else { // 2.2
771  if (complexType->attributeWildcard()) {
772  const XsdWildcard::Ptr wildcard(complexType->attributeWildcard());
773  if (!validateAttributeWildcard(attributeName, wildcard)) {
774  error(QtXmlPatterns::tr("Attribute %1 does not match the attribute wildcard.").arg(formatKeyword(m_namePool->displayName(attributeName))));
775  return false;
776  }
777 
778  if (wildcard->processContents() != XsdWildcard::Skip) {
779  const XsdAttribute::Ptr attributeDeclaration = attributeByName(attributeName);
780 
781  if (!attributeDeclaration) {
782  if (wildcard->processContents() == XsdWildcard::Strict) {
783  error(QtXmlPatterns::tr("Declaration for attribute %1 does not exist.").arg(formatKeyword(m_namePool->displayName(attributeName))));
784  return false;
785  }
786  } else {
787  if (BuiltinTypes::xsID->wxsTypeMatches(attributeDeclaration->type())) {
788  if (hasIDAttribute) {
789  error(QtXmlPatterns::tr("Element %1 contains two attributes of type %2.")
790  .arg(formatKeyword(declaration->displayName(m_namePool)))
791  .arg(formatKeyword("ID")));
792  return false;
793  }
794 
795  hasIDAttribute = true;
796  }
797 
798  if (!validateAttribute(attributeDeclaration, attribute(attributeName))) {
799  if (wildcard->processContents() == XsdWildcard::Strict) {
800  error(QtXmlPatterns::tr("Attribute %1 contains invalid content.").arg(formatKeyword(m_namePool->displayName(attributeName))));
801  return false;
802  }
803  }
804  }
805  }
806  } else {
807  error(QtXmlPatterns::tr("Element %1 contains unknown attribute %2.").arg(formatKeyword(declaration->displayName(m_namePool)))
808  .arg(formatKeyword(m_namePool->displayName(attributeName))));
809  return false;
810  }
811  }
812  }
813  }
814 
815  // 4
816  // so what?...
817 
818  // 5
819  // hmm...
820 
821  // 6
822  // TODO: check assertions
823 
824  // 7
825  // TODO: check type table restrictions
826 
827  // rememeber the type of that element node
828  m_model->setAssignedType(item().toNodeModelIndex(), type);
829 
830  return true;
831 }
The complex type has further elements or attributes and text as content.
QString displayName(const QXmlName qName) const
Definition: qnamepool.cpp:347
static const AtomicType::Ptr xsID
void setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type)
QString formatKeyword(const QString &keyword)
#define it(className, varName)
The attribute is not allowed to be there.
static bool hasIDAttributeUse(const XsdAttributeUse::List &uses)
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
XsdAttribute::Ptr attributeByName(const QXmlName &name) const
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
XsdAttributeUse::List attributeUses() const
ContentType::Ptr contentType() const
XsdWildcard::Ptr attributeWildcard() const
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
static const SchemaType::Ptr xsAnyType
No constraints at all: the item must simply be well-formed XML.
There must be a top-level declaration for the item available, or the item must have an xsi:type...
static XsdFacet::Hash mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context)
QSet< QXmlName > attributeNames() const
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
AnySimpleType::Ptr type() const
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
virtual QString displayName(const NamePool::Ptr &namePool) const
The element has a fixed value set.
static QString normalizedValue(const QString &value, const XsdFacet::Hash &facets)
QString attribute(const QXmlName &name) const
The complex type has only simple type content (e.g. text, number etc.)
bool validateAttributeWildcard(const QXmlName &attributeName, const XsdWildcard::Ptr &wildcard)
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)
QString simplified() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end, and that has each sequence o...
Definition: qstring.cpp:4415
ValueConstraint::Ptr valueConstraint() const
QSourceLocation sourceLocation() const
QExplicitlySharedDataPointer< XsdComplexType > Ptr
bool validateAttribute(const XsdAttributeUse::Ptr &declaration, const QString &value)
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75
The complex type has further elements or attributes but no text as content.
The class that provides methods for checking a string against a type.
The complex type has no further content.
virtual QXmlName name(const NamePool::Ptr &np) const =0
Returns the name of the type.
QVector< QXmlName > namespaceBindings(const QXmlNodeModelIndex &index) const
void createAndPushStateMachine(const XsdParticle::Ptr &particle)

◆ validateElementSimpleType()

bool XsdValidatingInstanceReader::validateElementSimpleType ( const XsdElement::Ptr declaration,
const SchemaType::Ptr type,
bool  isNilled 
)
private

Validates the current tag of the instance document against the given simple type of the element declaration.

Parameters
declarationThe element declaration to validate against.
typeThe type to validate against.
isNilledDefines whether the element is nilled by the instance document.
Note
The type can differ from the element declaration type if the instance document has defined it via xsi:type attribute.

Definition at line 539 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateElementType().

540 {
541  // @see http://www.w3.org/TR/xmlschema11-1/#d0e11749
542 
543  // 3.1.1
545  QSet<QXmlName> elementAttributes = attributeNames();
546  elementAttributes.subtract(allowedAttributes);
547  if (!elementAttributes.isEmpty()) {
548  error(QtXmlPatterns::tr("Element %1 contains not allowed attributes.").arg(formatKeyword(declaration->displayName(m_namePool))));
549  return false;
550  }
551 
552  // 3.1.2
553  if (hasChildElement()) {
554  error(QtXmlPatterns::tr("Element %1 contains not allowed child element.").arg(formatKeyword(declaration->displayName(m_namePool))));
555  return false;
556  }
557 
558  // 3.1.3
559  if (!isNilled) {
561 
562  QString actualValue;
563  if (hasChildText()) {
564  actualValue = XsdTypeChecker::normalizedValue(text(), facets);
565  } else {
566  if (declaration->valueConstraint())
567  actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
568  }
569 
570  QString errorMsg;
571  AnySimpleType::Ptr boundType;
572 
573  const XsdTypeChecker checker(m_context, namespaceBindings(item().toNodeModelIndex()), sourceLocation());
574  if (!checker.isValidString(actualValue, type, errorMsg, &boundType)) {
575  error(QtXmlPatterns::tr("Content of element %1 does not match its type definition: %2.").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg));
576  return false;
577  }
578 
579  // additional check
580  if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) {
581  const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets);
582  if (!text().isEmpty() && !checker.valuesAreEqual(actualValue, actualConstraintValue, type)) {
583  error(QtXmlPatterns::tr("Content of element %1 does not match defined value constraint.").arg(formatKeyword(declaration->displayName(m_namePool))));
584  return false;
585  }
586  }
587  }
588 
589  // 4 checked in validateElement already
590 
591  // rememeber the type of that element node
592  m_model->setAssignedType(item().toNodeModelIndex(), type);
593 
595  const QString actualValue = XsdTypeChecker::normalizedValue(text(), facets);
596 
597  if (BuiltinTypes::xsID->wxsTypeMatches(type)) {
598  addIdIdRefBinding(actualValue, declaration);
599  }
600 
601  if (m_idRefsType->wxsTypeMatches(type)) {
602  const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts);
603  for (int i = 0; i < idRefs.count(); ++i) {
604  m_idRefs.insert(idRefs.at(i));
605  }
606  } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(type)) {
607  m_idRefs.insert(actualValue);
608  }
609 
610  return true;
611 }
static const AtomicType::Ptr xsID
void setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type)
void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding)
QString formatKeyword(const QString &keyword)
bool isEmpty() const
Definition: qset.h:77
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
virtual bool wxsTypeMatches(const SchemaType::Ptr &other) const =0
static const AtomicType::Ptr xsIDREF
static XsdFacet::Hash mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context)
QSet< QXmlName > attributeNames() const
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
virtual QString displayName(const NamePool::Ptr &namePool) const
The element has a fixed value set.
const_iterator insert(const T &value)
Definition: qset.h:179
static QString normalizedValue(const QString &value, const XsdFacet::Hash &facets)
QSet< T > & subtract(const QSet< T > &other)
Definition: qset.h:270
static bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet< SchemaType::Ptr > &visitedTypes, SchemaType::Ptr &conflictingType)
ValueConstraint::Ptr valueConstraint() const
QSourceLocation sourceLocation() const
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
The class that provides methods for checking a string against a type.
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QVector< QXmlName > namespaceBindings(const QXmlNodeModelIndex &index) const

◆ validateElementType()

bool XsdValidatingInstanceReader::validateElementType ( const XsdElement::Ptr declaration,
const SchemaType::Ptr type,
bool  isNilled,
bool &  hasStateMachine 
)
private

Validates the current tag of the instance document against the given type of the element declaration.

Parameters
declarationThe element declaration to validate against.
typeThe type to validate against.
isNilledDefines whether the element is nilled by the instance document.
hasStateMachineUsed 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 type can differ from the element declaration type if the instance document has defined it via xsi:type attribute.

Definition at line 518 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateElement().

519 {
520  // @see http://www.w3.org/TR/xmlschema11-1/#d0e11749
521 
522  // 1 checked already
523 
524  // 2
525  if (type->isComplexType() && type->isDefinedBySchema()) {
526  if (XsdComplexType::Ptr(type)->isAbstract()) {
527  error(QtXmlPatterns::tr("Complex type %1 is not allowed to be abstract.").arg(formatType(m_namePool, type)));
528  return false;
529  }
530  }
531 
532  // 3
533  if (type->isSimpleType())
534  return validateElementSimpleType(declaration, type, isNilled); // 3.1
535  else
536  return validateElementComplexType(declaration, type, isNilled, hasStateMachine); // 3.2
537 }
virtual bool isSimpleType() const
Definition: qschematype.cpp:56
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
virtual bool isComplexType() const
Definition: qschematype.cpp:70
bool validateElementComplexType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine)
bool validateElementSimpleType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled)
virtual bool isAbstract() const
virtual bool isDefinedBySchema() const
Definition: qschematype.cpp:75

◆ validateIdentityConstraint()

bool XsdValidatingInstanceReader::validateIdentityConstraint ( const XsdElement::Ptr element,
const QXmlItem currentItem 
)
private

Validates the identity constraints of an element.

Definition at line 937 of file qxsdvalidatinginstancereader.cpp.

Referenced by read().

938 {
939  const XsdIdentityConstraint::List constraints = element->identityConstraints();
940 
941  for (int i = 0; i < constraints.count(); ++i) {
942  const XsdIdentityConstraint::Ptr constraint = constraints.at(i);
943 
944  TargetNode::Set targetNodeSet, qualifiedNodeSet;
945  selectNodeSets(element, currentItem, constraint, targetNodeSet, qualifiedNodeSet);
946 
947  if (constraint->category() == XsdIdentityConstraint::Unique) {
948  if (!validateUniqueIdentityConstraint(element, constraint, qualifiedNodeSet))
949  return false;
950  } else if (constraint->category() == XsdIdentityConstraint::Key) {
951  if (!validateKeyIdentityConstraint(element, constraint, targetNodeSet, qualifiedNodeSet))
952  return false;
953  }
954  }
955 
956  // we do the keyref check in a separated run to make sure that all keys are available
957  for (int i = 0; i < constraints.count(); ++i) {
958  const XsdIdentityConstraint::Ptr constraint = constraints.at(i);
959  if (constraint->category() == XsdIdentityConstraint::KeyReference) {
960  TargetNode::Set targetNodeSet, qualifiedNodeSet;
961  selectNodeSets(element, currentItem, constraint, targetNodeSet, qualifiedNodeSet);
962 
963  if (!validateKeyRefIdentityConstraint(element, constraint, qualifiedNodeSet))
964  return false;
965  }
966  }
967 
968  return true;
969 }
bool validateKeyIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &targetNodeSet, const TargetNode::Set &qualifiedNodeSet)
XsdIdentityConstraint::List identityConstraints() const
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
bool validateKeyRefIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet)
bool selectNodeSets(const XsdElement::Ptr &element, const QXmlItem &currentItem, const XsdIdentityConstraint::Ptr &constraint, TargetNode::Set &targetNodeSet, TargetNode::Set &qualifiedNodeSet)
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The constraint is an unique constraint.
The constraint is a key constraint.
bool validateUniqueIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet)

◆ validateKeyIdentityConstraint()

bool XsdValidatingInstanceReader::validateKeyIdentityConstraint ( const XsdElement::Ptr element,
const XsdIdentityConstraint::Ptr constraint,
const TargetNode::Set targetNodeSet,
const TargetNode::Set qualifiedNodeSet 
)
private

Validates the key identity constraint of the element.

Definition at line 1000 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateIdentityConstraint().

1001 {
1002  // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243
1003 
1004  // 4.2
1006 
1007  // 4.2.1
1008  if (targetNodeSet.count() != qualifiedNodeSet.count()) {
1009  error(QtXmlPatterns::tr("Key constraint %1 contains absent fields.").arg(formatKeyword(constraint->displayName(m_namePool))));
1010  return false;
1011  }
1012 
1013  // 4.2.2
1014  if (!validateUniqueIdentityConstraint(element, constraint, qualifiedNodeSet))
1015  return false;
1016 
1017  // 4.2.3
1018  QSetIterator<TargetNode> it(qualifiedNodeSet);
1019  while (it.hasNext()) {
1020  const TargetNode node = it.next();
1021  const QVector<QXmlItem> fieldItems = node.fieldItems();
1022  for (int i = 0; i < fieldItems.count(); ++i) {
1023  const QXmlNodeModelIndex index = fieldItems.at(i).toNodeModelIndex();
1024  if (m_model->kind(index) == QXmlNodeModelIndex::Element) {
1025  const XsdElement::Ptr declaration = m_model->assignedElement(index);
1026  if (declaration && declaration->isNillable()) {
1027  error(QtXmlPatterns::tr("Key constraint %1 contains references nillable element %2.")
1028  .arg(formatKeyword(constraint->displayName(m_namePool)))
1029  .arg(formatKeyword(declaration->displayName(m_namePool))));
1030  return false;
1031  }
1032  }
1033  }
1034  }
1035 
1036  m_idcKeys.insert(constraint->name(m_namePool), qualifiedNodeSet);
1037 
1038  return true;
1039 }
The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeM...
QString formatKeyword(const QString &keyword)
#define it(className, varName)
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
A helper class for validating identity constraints.
virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &ni) const
Returns a value indicating the kind of node identified by ni.
XsdElement::Ptr assignedElement(const QXmlNodeModelIndex &index) const
virtual QString displayName(const NamePool::Ptr &namePool) const
int count() const
Definition: qset.h:178
virtual QXmlName name(const NamePool::Ptr &namePool) const
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
An implementation of SourceLocationReflection that takes a QSourceLocation.
QSourceLocation sourceLocation() const
quint16 index
QVector< QXmlItem > fieldItems() const
QXmlNodeModelIndex toNodeModelIndex() const
If this QXmlItem represents a node, it returns the item as a QXmlNodeModelIndex.
bool validateUniqueIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet)

◆ validateKeyRefIdentityConstraint()

bool XsdValidatingInstanceReader::validateKeyRefIdentityConstraint ( const XsdElement::Ptr element,
const XsdIdentityConstraint::Ptr constraint,
const TargetNode::Set qualifiedNodeSet 
)
private

Validates the keyref identity constraint of the element.

Definition at line 1041 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateIdentityConstraint().

1042 {
1043  // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243
1044 
1045  // 4.3
1047 
1048  const TargetNode::Set keySet = m_idcKeys.value(constraint->referencedKey()->name(m_namePool));
1049 
1050  QSetIterator<TargetNode> it(qualifiedNodeSet);
1051  while (it.hasNext()) {
1052  const TargetNode node = it.next();
1053 
1054  bool foundMatching = false;
1055 
1056  QSetIterator<TargetNode> keyIt(keySet);
1057  while (keyIt.hasNext()) {
1058  const TargetNode keyNode = keyIt.next();
1059 
1060  if (node.fieldsAreEqual(keyNode, m_namePool, m_context, &reflection)) {
1061  foundMatching = true;
1062  break;
1063  }
1064  }
1065 
1066  if (!foundMatching) {
1067  error(QtXmlPatterns::tr("No referenced value found for key reference %1.").arg(formatKeyword(constraint->displayName(m_namePool))));
1068  return false;
1069  }
1070  }
1071 
1072  return true;
1073 }
QString formatKeyword(const QString &keyword)
#define it(className, varName)
bool fieldsAreEqual(const TargetNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const
A helper class for validating identity constraints.
virtual QString displayName(const NamePool::Ptr &namePool) const
virtual QXmlName name(const NamePool::Ptr &namePool) const
An implementation of SourceLocationReflection that takes a QSourceLocation.
QSourceLocation sourceLocation() const
XsdIdentityConstraint::Ptr referencedKey() const

◆ validateUniqueIdentityConstraint()

bool XsdValidatingInstanceReader::validateUniqueIdentityConstraint ( const XsdElement::Ptr element,
const XsdIdentityConstraint::Ptr constraint,
const TargetNode::Set qualifiedNodeSet 
)
private

Validates the unique identity constraint of the element.

Definition at line 971 of file qxsdvalidatinginstancereader.cpp.

Referenced by validateIdentityConstraint(), and validateKeyIdentityConstraint().

972 {
973  // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243
974 
975  // 4.1
977 
978  QSetIterator<TargetNode> it(qualifiedNodeSet);
979  while (it.hasNext()) {
980  const TargetNode node = it.next();
981  QSetIterator<TargetNode> innerIt(qualifiedNodeSet);
982  while (innerIt.hasNext()) {
983  const TargetNode innerNode = innerIt.next();
984 
985  if (node == innerNode) // do not compare with ourself
986  continue;
987 
988  if (node.fieldsAreEqual(innerNode, m_namePool, m_context, &reflection)) {
989  error(QtXmlPatterns::tr("Non-unique value found for constraint %1.").arg(formatKeyword(constraint->displayName(m_namePool))));
990  return false;
991  }
992  }
993  }
994 
995  m_idcKeys.insert(constraint->name(m_namePool), qualifiedNodeSet);
996 
997  return true;
998 }
QString formatKeyword(const QString &keyword)
#define it(className, varName)
bool fieldsAreEqual(const TargetNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const
A helper class for validating identity constraints.
virtual QString displayName(const NamePool::Ptr &namePool) const
virtual QXmlName name(const NamePool::Ptr &namePool) const
An implementation of SourceLocationReflection that takes a QSourceLocation.
QSourceLocation sourceLocation() const

Properties

◆ m_anyType

XsdComplexType::Ptr QPatternist::XsdValidatingInstanceReader::m_anyType
private

Definition at line 283 of file qxsdvalidatinginstancereader_p.h.

Referenced by anyType().

◆ m_documentUri

QUrl QPatternist::XsdValidatingInstanceReader::m_documentUri
private

Definition at line 282 of file qxsdvalidatinginstancereader_p.h.

Referenced by createXQuery(), and validate().

◆ m_idcKeys

QHash<QXmlName, TargetNode::Set> QPatternist::XsdValidatingInstanceReader::m_idcKeys
private

◆ m_idRefs

QSet<QString> QPatternist::XsdValidatingInstanceReader::m_idRefs
private

◆ m_idRefsType

SchemaType::Ptr QPatternist::XsdValidatingInstanceReader::m_idRefsType
private

◆ m_mergedSchemas

MergedSchemas QPatternist::XsdValidatingInstanceReader::m_mergedSchemas
private

Definition at line 273 of file qxsdvalidatinginstancereader_p.h.

Referenced by addSchema().

◆ m_model

XsdValidatedXmlNodeModel::Ptr QPatternist::XsdValidatingInstanceReader::m_model
private

◆ m_namePool

const NamePool::Ptr QPatternist::XsdValidatingInstanceReader::m_namePool
private

◆ m_processedNamespaces

QSet<QString> QPatternist::XsdValidatingInstanceReader::m_processedNamespaces
private

Definition at line 284 of file qxsdvalidatinginstancereader_p.h.

Referenced by validate().

◆ m_processedSchemaLocations

QSet<QString> QPatternist::XsdValidatingInstanceReader::m_processedSchemaLocations
private

Definition at line 285 of file qxsdvalidatinginstancereader_p.h.

Referenced by validate().

◆ m_schema

XsdSchema::Ptr QPatternist::XsdValidatingInstanceReader::m_schema
private

◆ m_stateMachines

QStack<XsdStateMachine<XsdTerm::Ptr> > QPatternist::XsdValidatingInstanceReader::m_stateMachines
private

Definition at line 281 of file qxsdvalidatinginstancereader_p.h.

Referenced by createAndPushStateMachine(), read(), and validate().

◆ m_xsiNilName

const QXmlName QPatternist::XsdValidatingInstanceReader::m_xsiNilName
private

◆ m_xsiNoNamespaceSchemaLocationName

const QXmlName QPatternist::XsdValidatingInstanceReader::m_xsiNoNamespaceSchemaLocationName
private

◆ m_xsiSchemaLocationName

const QXmlName QPatternist::XsdValidatingInstanceReader::m_xsiSchemaLocationName
private

◆ m_xsiTypeName

const QXmlName QPatternist::XsdValidatingInstanceReader::m_xsiTypeName
private

The documentation for this class was generated from the following files: