RdpPattern ValidateTextOnlyCore() { RdpPattern ts = memo.TextOnlyDeriv(vState); ts = TextDeriv(ts, cachedValue, reader); if (Util.IsWhitespace(cachedValue)) { ts = vState.Choice(ts); } return(ts); }
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); }
// choice :: Pattern -> Pattern -> Pattern internal static RdpPattern Choice(RdpPattern p1, RdpPattern p2) { return(p1.Choice(p2)); }