in src/xercesc/validators/common/SimpleContentModel.cpp [276:482]
bool SimpleContentModel::validateContentSpecial(QName** const children
, XMLSize_t childCount
, unsigned int
, GrammarResolver* const pGrammarResolver
, XMLStringPool* const pStringPool
, XMLSize_t* indexFailingChild
, MemoryManager* const) const
{
SubstitutionGroupComparator comparator(pGrammarResolver, pStringPool);
//
// According to the type of operation, we do the correct type of
// content check.
//
unsigned int index;
switch(fOp & 0x0f)
{
case ContentSpecNode::Leaf :
//
// There can only be one child and it has to be of the
// element type we stored.
//
if (!childCount)
{
*indexFailingChild=0;
return false;
}
if ((children[0]->getURI() != fFirstChild->getURI()) ||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))
{
if (!comparator.isEquivalentTo(children[0], fFirstChild))
{
*indexFailingChild=0;
return false;
}
}
if (childCount > 1)
{
*indexFailingChild=1;
return false;
}
break;
case ContentSpecNode::ZeroOrOne :
//
// If the child count is greater than one, then obviously
// bad. Otherwise, if its one, then the one child must be
// of the type we stored.
//
if ((childCount == 1) &&
((children[0]->getURI() != fFirstChild->getURI()) ||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())))
{
if(!comparator.isEquivalentTo(children[0], fFirstChild))
{
*indexFailingChild=0;
return false;
}
}
if (childCount > 1)
{
*indexFailingChild=1;
return false;
}
break;
case ContentSpecNode::ZeroOrMore :
//
// If the child count is zero, that's fine. If its more than
// zero, then make sure that all children are of the element
// type that we stored.
//
if (childCount > 0)
{
for (index = 0; index < childCount; index++)
{
if ((children[index]->getURI() != fFirstChild->getURI()) ||
!XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart()))
{
if (!comparator.isEquivalentTo(children[index], fFirstChild))
{
*indexFailingChild=index;
return false;
}
}
}
}
break;
case ContentSpecNode::OneOrMore :
//
// If the child count is zero, that's an error. If its more
// than zero, then make sure that all children are of the
// element type that we stored.
//
if (childCount == 0)
{
*indexFailingChild=0;
return false;
}
for (index = 0; index < childCount; index++)
{
if ((children[index]->getURI() != fFirstChild->getURI()) ||
!XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart()))
{
if (!comparator.isEquivalentTo(children[index], fFirstChild))
{
*indexFailingChild=index;
return false;
}
}
}
break;
case ContentSpecNode::Choice :
//
// There can only be one child, and it must be one of the
// two types we stored.
//
if (!childCount)
{
*indexFailingChild=0;
return false;
}
if (((children[0]->getURI() != fFirstChild->getURI()) ||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) &&
((children[0]->getURI() != fSecondChild->getURI()) ||
!XMLString::equals(children[0]->getLocalPart(), fSecondChild->getLocalPart())))
{
if (!comparator.isEquivalentTo(children[0], fFirstChild) &&
!comparator.isEquivalentTo(children[0], fSecondChild) )
{
*indexFailingChild=0;
return false;
}
}
if (childCount > 1)
{
*indexFailingChild=1;
return false;
}
break;
case ContentSpecNode::Sequence :
//
// There must be two children and they must be the two values
// we stored, in the stored order. So first check the obvious
// problem of an empty content, which would never be valid
// in this content mode.
//
if (!childCount)
{
*indexFailingChild=0;
return false;
}
// test first child
if ((children[0]->getURI() != fFirstChild->getURI()) ||
!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))
{
if(!comparator.isEquivalentTo(children[0], fFirstChild))
{
*indexFailingChild=0;
return false;
}
}
// test second child, if present
if( childCount == 1)
{
// missing second child
*indexFailingChild=1;
return false;
}
else
{
if ((children[1]->getURI() != fSecondChild->getURI()) ||
!XMLString::equals(children[1]->getLocalPart(), fSecondChild->getLocalPart()))
{
if (!comparator.isEquivalentTo(children[1], fSecondChild))
{
*indexFailingChild=1;
return false;
}
}
if (childCount > 2) {
*indexFailingChild=2;
return false;
}
}
break;
default :
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
break;
}
return true;
}