private void ParseStep(string xpath, int pos, ArrayList steps, ArrayList paths, ValidationEventHandler h, XmlSchema schema) { pos = SkipWhitespace(xpath, pos); if (xpath.Length == pos) { error(h, "Empty xpath expression is specified"); return; } XsdIdentityStep step = new XsdIdentityStep(); switch (xpath [pos]) { case '@': if (isSelector) { error(h, "Selector cannot include attribute axes."); currentPath = null; return; } pos++; step.IsAttribute = true; pos = SkipWhitespace(xpath, pos); if (xpath.Length > pos && xpath [pos] == '*') { pos++; step.IsAnyName = true; break; } goto default; case '.': pos++; // do nothing ;-) step.IsCurrent = true; break; case '*': pos++; step.IsAnyName = true; break; case 'c': if (xpath.Length > pos + 5 && xpath.IndexOf("child", pos, 5) == pos) { int tmp = pos; pos += 5; pos = SkipWhitespace(xpath, pos); if (xpath.Length > pos && xpath [pos] == ':' && xpath [pos + 1] == ':') { pos += 2; if (xpath.Length > pos && xpath [pos] == '*') { pos++; step.IsAnyName = true; break; } pos = SkipWhitespace(xpath, pos); } else { pos = tmp; } } goto default; case 'a': if (xpath.Length > pos + 9 && xpath.IndexOf("attribute", pos, 9) == pos) { int tmp = pos; pos += 9; pos = SkipWhitespace(xpath, pos); if (xpath.Length > pos && xpath [pos] == ':' && xpath [pos + 1] == ':') { if (isSelector) { error(h, "Selector cannot include attribute axes."); currentPath = null; return; } pos += 2; step.IsAttribute = true; if (xpath.Length > pos && xpath [pos] == '*') { pos++; step.IsAnyName = true; break; } pos = SkipWhitespace(xpath, pos); } else { pos = tmp; } } goto default; default: int nameStart = pos; while (xpath.Length > pos) { if (!XmlChar.IsNCNameChar(xpath [pos])) { break; } else { pos++; } } if (pos == nameStart) { error(h, "Invalid path format for a field."); this.currentPath = null; return; } if (xpath.Length == pos || xpath [pos] != ':') { step.Name = xpath.Substring(nameStart, pos - nameStart); } else { string prefix = xpath.Substring(nameStart, pos - nameStart); pos++; if (xpath.Length > pos && xpath [pos] == '*') { string ns = nsmgr.LookupNamespace(prefix, false); if (ns == null) { error(h, "Specified prefix '" + prefix + "' is not declared."); this.currentPath = null; return; } step.NsName = ns; pos++; } else { int localNameStart = pos; while (xpath.Length > pos) { if (!XmlChar.IsNCNameChar(xpath [pos])) { break; } else { pos++; } } step.Name = xpath.Substring(localNameStart, pos - localNameStart); string ns = nsmgr.LookupNamespace(prefix, false); if (ns == null) { error(h, "Specified prefix '" + prefix + "' is not declared."); this.currentPath = null; return; } step.Namespace = ns; } } break; } if (!step.IsCurrent) // Current step is meaningless, other than its representation. { steps.Add(step); } pos = SkipWhitespace(xpath, pos); if (xpath.Length == pos) { currentPath.OrderedSteps = (XsdIdentityStep [])steps.ToArray(typeof(XsdIdentityStep)); paths.Add(currentPath); return; } else if (xpath [pos] == '/') { pos++; if (step.IsAttribute) { error(h, "Unexpected xpath token after Attribute NameTest."); this.currentPath = null; return; } this.ParseStep(xpath, pos, steps, paths, h, schema); if (currentPath == null) // For ValidationEventHandler { return; } currentPath.OrderedSteps = (XsdIdentityStep [])steps.ToArray(typeof(XsdIdentityStep)); } else if (xpath [pos] == '|') { pos++; currentPath.OrderedSteps = (XsdIdentityStep [])steps.ToArray(typeof(XsdIdentityStep)); paths.Add(this.currentPath); this.currentPath = new XsdIdentityPath(); this.ParsePath(xpath, pos, paths, h, schema); } else { error(h, "Unexpected xpath token after NameTest."); this.currentPath = null; return; } }
private void ParseStep(string xpath, int pos, ArrayList steps, ArrayList paths, ValidationEventHandler h, XmlSchema schema) { pos = this.SkipWhitespace(xpath, pos); if (xpath.Length == pos) { base.error(h, "Empty xpath expression is specified"); return; } XsdIdentityStep xsdIdentityStep = new XsdIdentityStep(); char c = xpath[pos]; switch (c) { case 'a': if (xpath.Length > pos + 9 && xpath.IndexOf("attribute", pos, 9) == pos) { int num = pos; pos += 9; pos = this.SkipWhitespace(xpath, pos); if (xpath.Length > pos && xpath[pos] == ':' && xpath[pos + 1] == ':') { if (this.isSelector) { base.error(h, "Selector cannot include attribute axes."); this.currentPath = null; return; } pos += 2; xsdIdentityStep.IsAttribute = true; if (xpath.Length > pos && xpath[pos] == '*') { pos++; xsdIdentityStep.IsAnyName = true; goto IL_3D5; } pos = this.SkipWhitespace(xpath, pos); } else { pos = num; } } break; default: if (c == '*') { pos++; xsdIdentityStep.IsAnyName = true; goto IL_3D5; } if (c == '.') { pos++; xsdIdentityStep.IsCurrent = true; goto IL_3D5; } if (c == '@') { if (this.isSelector) { base.error(h, "Selector cannot include attribute axes."); this.currentPath = null; return; } pos++; xsdIdentityStep.IsAttribute = true; pos = this.SkipWhitespace(xpath, pos); if (xpath.Length > pos && xpath[pos] == '*') { pos++; xsdIdentityStep.IsAnyName = true; goto IL_3D5; } } break; case 'c': if (xpath.Length > pos + 5 && xpath.IndexOf("child", pos, 5) == pos) { int num2 = pos; pos += 5; pos = this.SkipWhitespace(xpath, pos); if (xpath.Length > pos && xpath[pos] == ':' && xpath[pos + 1] == ':') { pos += 2; if (xpath.Length > pos && xpath[pos] == '*') { pos++; xsdIdentityStep.IsAnyName = true; goto IL_3D5; } pos = this.SkipWhitespace(xpath, pos); } else { pos = num2; } } break; } int num3 = pos; while (xpath.Length > pos) { if (!XmlChar.IsNCNameChar((int)xpath[pos])) { break; } pos++; } if (pos == num3) { base.error(h, "Invalid path format for a field."); this.currentPath = null; return; } if (xpath.Length == pos || xpath[pos] != ':') { xsdIdentityStep.Name = xpath.Substring(num3, pos - num3); } else { string text = xpath.Substring(num3, pos - num3); pos++; if (xpath.Length > pos && xpath[pos] == '*') { string text2 = this.nsmgr.LookupNamespace(text, false); if (text2 == null) { base.error(h, "Specified prefix '" + text + "' is not declared."); this.currentPath = null; return; } xsdIdentityStep.NsName = text2; pos++; } else { int num4 = pos; while (xpath.Length > pos) { if (!XmlChar.IsNCNameChar((int)xpath[pos])) { break; } pos++; } xsdIdentityStep.Name = xpath.Substring(num4, pos - num4); string text3 = this.nsmgr.LookupNamespace(text, false); if (text3 == null) { base.error(h, "Specified prefix '" + text + "' is not declared."); this.currentPath = null; return; } xsdIdentityStep.Namespace = text3; } } IL_3D5: if (!xsdIdentityStep.IsCurrent) { steps.Add(xsdIdentityStep); } pos = this.SkipWhitespace(xpath, pos); if (xpath.Length == pos) { this.currentPath.OrderedSteps = (XsdIdentityStep[])steps.ToArray(typeof(XsdIdentityStep)); paths.Add(this.currentPath); return; } if (xpath[pos] == '/') { pos++; if (xsdIdentityStep.IsAttribute) { base.error(h, "Unexpected xpath token after Attribute NameTest."); this.currentPath = null; return; } this.ParseStep(xpath, pos, steps, paths, h, schema); if (this.currentPath == null) { return; } this.currentPath.OrderedSteps = (XsdIdentityStep[])steps.ToArray(typeof(XsdIdentityStep)); } else { if (xpath[pos] != '|') { base.error(h, "Unexpected xpath token after NameTest."); this.currentPath = null; return; } pos++; this.currentPath.OrderedSteps = (XsdIdentityStep[])steps.ToArray(typeof(XsdIdentityStep)); paths.Add(this.currentPath); this.currentPath = new XsdIdentityPath(); this.ParsePath(xpath, pos, paths, h, schema); } }