Beispiel #1
0
		// choice :: Pattern -> Pattern -> Pattern
		internal static RdpPattern Choice (RdpPattern p1, RdpPattern p2)
		{
			return p1.Choice (p2);
		}
		public override bool Read ()
		{
			PrepareState ();

			// If the input XmlReader is already positioned on
			// the first node to validate, skip Read() here
			// (idea by Alex).
			bool ret;
			if (firstRead) {
				firstRead = false;
				if (reader.ReadState == ReadState.Initial)
					ret = reader.Read ();
				else
					ret = !((reader.ReadState == ReadState.Closed) || (reader.ReadState == ReadState.EndOfFile));
			}
			else
				ret = reader.Read ();

			// Process pending text node validation if required.
			if (cachedValue != null)
				ValidateText (ret);
			else if (cachedValue == null &&
				reader.NodeType == XmlNodeType.EndElement && 
				startElementDepth == reader.Depth)
				ValidateWeakMatch3 ();

			switch (reader.NodeType) {
			case XmlNodeType.Element:
				inContent = true;
				// StartTagOpenDeriv
				prevState = vState;
				vState = memo.StartTagOpenDeriv (vState,
					reader.LocalName, reader.NamespaceURI);
				if (vState.PatternType == RelaxngPatternType.NotAllowed) {
					if (InvalidNodeFound != null)
						vState = HandleError (String.Format ("Invalid start tag found. LocalName = {0}, NS = {1}.", reader.LocalName, reader.NamespaceURI), true, prevState, RecoverFromInvalidStartTag);
				}

				// AttsDeriv equals to for each AttDeriv
				string elementNS = reader.NamespaceURI;
				if (reader.MoveToFirstAttribute ()) {
					do {
						if (reader.NamespaceURI == "http://www.w3.org/2000/xmlns/")
							continue;

						RdpPattern savedState = vState;
						prevState = vState;
						string attrNS = reader.NamespaceURI;

						vState = memo.StartAttDeriv (vState, reader.LocalName, attrNS);
						if (vState == RdpNotAllowed.Instance) {
							vState = HandleError (String.Format ("Invalid attribute occurence found. LocalName = {0}, NS = {1}.", reader.LocalName, reader.NamespaceURI), false, savedState, p => p);
							continue; // the following steps are ignored.
						}
						prevState = vState;
						vState = memo.TextOnlyDeriv (vState);
						vState = TextDeriv (vState, reader.Value, reader);
						if (Util.IsWhitespace (reader.Value))
							vState = vState.Choice (prevState);
						if (vState == RdpNotAllowed.Instance)
							vState = HandleError (String.Format ("Invalid attribute value is found. Value = '{0}'", reader.Value), false, prevState, RecoverFromInvalidText);
						prevState = vState;
						vState = memo.EndAttDeriv (vState);
						if (vState == RdpNotAllowed.Instance)
							vState = HandleError (String.Format ("Invalid attribute value is found. Value = '{0}'", reader.Value), false, prevState, RecoverFromInvalidEnd);
					} while (reader.MoveToNextAttribute ());
					MoveToElement ();
				}

				// StarTagCloseDeriv
				prevState = vState;
				vState = memo.StartTagCloseDeriv (vState);
				if (vState.PatternType == RelaxngPatternType.NotAllowed)
					vState = HandleError (String.Format ("Invalid start tag closing found. LocalName = {0}, NS = {1}.", reader.LocalName, reader.NamespaceURI), false, prevState, RecoverFromInvalidStartTagClose);

				// if it is empty, then redirect to EndElement
				if (reader.IsEmptyElement) {
					ValidateWeakMatch3 ();
					goto case XmlNodeType.EndElement;
				}
				break;
			case XmlNodeType.EndElement:
				if (reader.Depth == 0)
					inContent = false;
				// EndTagDeriv
				prevState = vState;
				vState = memo.EndTagDeriv (vState);
				if (vState.PatternType == RelaxngPatternType.NotAllowed)
					vState = HandleError (String.Format ("Invalid end tag found. LocalName = {0}, NS = {1}.", reader.LocalName, reader.NamespaceURI), true, prevState, RecoverFromInvalidEnd);
				break;
			case XmlNodeType.Whitespace:
				if (inContent)
					goto case XmlNodeType.Text;
				break;
			case XmlNodeType.CDATA:
			case XmlNodeType.Text:
			case XmlNodeType.SignificantWhitespace:
				// Whitespace cannot be skipped because data and
				// value types are required to validate whitespaces.
				cachedValue += Value;
				break;
			}

			if (reader.NodeType == XmlNodeType.Element && !reader.IsEmptyElement)
				startElementDepth = reader.Depth;
			else if (reader.NodeType == XmlNodeType.EndElement)
				startElementDepth = -1;

			return ret;
		}