Beispiel #1
0
        private RelaxngRef ReadRefPattern()
        {
            RelaxngRef r = new RelaxngRef();

            FillLocation(r);
            expect("ref");
            r.Name = GetNameAttribute();
            if (!IsEmptyElement)
            {
                Read();
                expectEnd("ref");
            }
            else
            {
                Read();
            }
            return(r);
        }
Beispiel #2
0
		private RelaxngRef ReadRefPattern ()
		{
			RelaxngRef r = new RelaxngRef ();
			FillLocation (r);
			expect ("ref");
			r.Name = GetNameAttribute ();
			if (!IsEmptyElement) {
				Read ();
				expectEnd ("ref");
			}
			else
				Read ();
			return r;
		}
Beispiel #3
0
		RelaxngPattern CreatePatternFromParticleCore (XmlSchemaParticle xsdp)
		{
			XmlSchemaGroupBase gb = xsdp as XmlSchemaGroupBase;
			if (xsdp is XmlSchemaAny) {
				RelaxngRef r = new RelaxngRef ();
				r.Name = "anyType";
				return r;
			}
			if (gb is XmlSchemaSequence) {
				RelaxngGroup grp = new RelaxngGroup ();
				foreach (XmlSchemaParticle xsdc in gb.Items)
					grp.Patterns.Add (CreatePatternFromParticle (xsdc));
				return grp;
			}
			if (gb is XmlSchemaChoice) {
				RelaxngChoice rc = new RelaxngChoice ();
				foreach (XmlSchemaParticle xsdc in gb.Items)
					rc.Patterns.Add (CreatePatternFromParticle (xsdc));
				return rc;
			}
			return CreateElement ((XmlSchemaElement) xsdp);
		}
Beispiel #4
0
		RelaxngGrammar DtdXsd2Rng (XmlSchema xsd, string ns)
		{
			g = new RelaxngGrammar ();
			g.DefaultNamespace = ns;
			RelaxngStart start = new RelaxngStart ();
			g.Starts.Add (start);
			RelaxngChoice choice = new RelaxngChoice ();
			start.Pattern = choice;

			// There are only elements.
			foreach (XmlSchemaElement el in xsd.Items) {
				RelaxngDefine def = DefineElement (el);
				g.Defines.Add (def);
				RelaxngRef dref = new RelaxngRef ();
				dref.Name = def.Name;
				choice.Patterns.Add (dref);
			}

			return g;
		}
Beispiel #5
0
		RelaxngPattern CreateElement (XmlSchemaElement xse)
		{
			if (xse.RefName != XmlQualifiedName.Empty) {
				RelaxngRef r = new RelaxngRef ();
				r.Name = xse.RefName.Name;
				// namespace means nothing here.
				return r;
			}

			RelaxngElement re = new RelaxngElement ();
			RelaxngName name = new RelaxngName ();
			name.LocalName = xse.Name;
			re.NameClass = name;

			XmlSchemaComplexType ct = xse.SchemaType as XmlSchemaComplexType;

			foreach (XmlSchemaAttribute a in ct.Attributes)
				re.Patterns.Add (CreateAttribute (a));

			RelaxngPattern rpart;
			if (ct.Particle == null)
				rpart = new RelaxngEmpty ();
			else
				rpart = CreatePatternFromParticle (ct.Particle);

			if (ct.IsMixed) {
				if (rpart.PatternType != RelaxngPatternType.Empty) {
					RelaxngMixed mixed = new RelaxngMixed ();
					mixed.Patterns.Add (rpart);
					rpart = mixed;
				} else {
					rpart = new RelaxngText ();
				}
			}

			re.Patterns.Add (rpart);

			return re;
		}
		private void ProcessSequence (RelaxngElement ct, RelaxngGroup s,
			ref int position, ref bool consumed,
			bool isNew)
		{
			RelaxngMixed m = s.Patterns.Count > 0 ? s.Patterns [0] as RelaxngMixed : null;
			RelaxngPatternList pl = m != null ?
				m.Patterns : s.Patterns;
			for (int i = 0; i < position; i++) {
				RelaxngPattern p = pl [i];
				RelaxngRef iel = p as RelaxngRef;
				if (iel == null) {
					RelaxngOneOrMore oom =
						p as RelaxngOneOrMore;
					iel = (RelaxngRef) oom.Patterns [0];
				}
				if (ElementMatches (iel)) {
					// Sequence element type violation
					// might happen (might not, but we
					// cannot backtrack here). So switch
					// to sequence of choice* here.
					ProcessLax (ToSequenceOfChoice (ct, s));
					return;
				}
			}

			if (pl.Count <= position) {
				QName name = new QName (source.LocalName,
					source.NamespaceURI);
				RelaxngDefine nel = GetGlobalElement (name);
				if (nel != null)
					InferElement (nel, false);
				else {
					nel = CreateGlobalElement (name); // used to be CreateElement().
					InferElement (nel, true);
				}
				RelaxngRef re = new RelaxngRef ();
				re.Name = nel.Name;
				pl.Add (re);
				consumed = true;
				return;
			}
			RelaxngPattern c = pl [position];
			RelaxngRef el = c as RelaxngRef;
			if (el == null) {
				RelaxngOneOrMore oom = c as RelaxngOneOrMore;
				el = (RelaxngRef) oom.Patterns [0];
			}
			if (el == null)
				throw Error (s, String.Format ("Target complex type content sequence has an unacceptable type of particle {0}", s.Patterns [position]));
			bool matches = ElementMatches (el);
			if (matches) {
				if (consumed && c is RelaxngRef) {
					RelaxngOneOrMore oom = new RelaxngOneOrMore ();
					oom.Patterns.Add (el);
					pl [position] = oom;
				}
				InferElement (el, false);
				source.MoveToContent ();
				switch (source.NodeType) {
				case XmlNodeType.None:
					if (source.NodeType ==
						XmlNodeType.Element)
						goto case XmlNodeType.Element;
					else if (source.NodeType ==
						XmlNodeType.EndElement)
						goto case XmlNodeType.EndElement;
					break;
				case XmlNodeType.Element:
					ProcessSequence (ct, s, ref position,
						ref consumed, isNew);
					break;
				case XmlNodeType.Text:
				case XmlNodeType.CDATA:
				case XmlNodeType.SignificantWhitespace:
					MarkAsMixed (ct);
					source.ReadString ();
					goto case XmlNodeType.None;
				case XmlNodeType.Whitespace:
					source.ReadString ();
					goto case XmlNodeType.None;
				case XmlNodeType.EndElement:
					return;
				default:
					source.Read ();
					break;
				}
			}
			else {
				if (consumed) {
					position++;
					consumed = false;
					ProcessSequence (ct, s,
						ref position, ref consumed,
						isNew);
				}
				else
					ProcessLax (ToSequenceOfChoice (ct, s));
			}
		}
Beispiel #7
0
		public void WriteRef (RelaxngRef r)
		{
			if (IsKeyword (r.Name))
				w.Write ('\\');
			w.Write (r.Name);
		}
		private bool ElementMatches (RelaxngRef el)
		{
			RelaxngDefine def = elements [new QName (
				source.LocalName, source.NamespaceURI)]
				as RelaxngDefine;
			return def != null && def.Name == el.Name;
		}
		private void ProcessLax (RelaxngSingleContentPattern scp)
		{
			RelaxngChoice c = (RelaxngChoice) scp.Patterns [0];
			foreach (RelaxngPattern p in c.Patterns) {
				RelaxngRef el = p as RelaxngRef;
				if (el == null) {
					RelaxngOneOrMore oom =
						(RelaxngOneOrMore) p;
					el = (RelaxngRef) oom.Patterns [0];
				}
				if (el == null)
					throw Error (c, String.Format ("Target pattern contains unacceptable child pattern {0}. Only ref is allowed here."));
				if (ElementMatches (el)) {
					InferElement (el, false);
					return;
				}
			}
			// append a new element particle to lax term.
			QName qname = new QName (
				source.LocalName, source.NamespaceURI);
			RelaxngDefine def = GetGlobalElement (qname);
			if (def == null) {
				def = CreateGlobalElement (qname); // used to be CreateElement().
				InferElement (def, true);
			}
			else
				InferElement (def, false);
			RelaxngRef nel = new RelaxngRef ();
			nel.Name = def.Name;
			c.Patterns.Add (nel);
		}
		// It returns RelaxngAttribute for local attribute, and
		// RelaxngRef for global attribute.
		private RelaxngPattern InferNewAttribute (
			QName attrName, bool isNewTypeDefinition)
		{
			RelaxngPattern p = null;
			bool mergedRequired = false;
			if (attrName.Namespace.Length > 0) {
				// global attribute; might be already defined.
				// (Actually RELAX NG has no concept of "global
				// attributes" but it is still useful to
				// represent attributes in global scope.
				RelaxngDefine attr = GetGlobalAttribute (
					attrName);
				if (attr == null) {
					attr = CreateGlobalAttribute (attrName);
					attr.Patterns.Add (CreateSimplePattern (
						InferSimpleType (source.Value)));
				} else {
					RelaxngAttribute a = attr.Patterns [0] as RelaxngAttribute;
					if (a != null)
						mergedRequired = true;
					else {
						RelaxngOptional opt =
							(RelaxngOptional) attr.Patterns [0];
						a = (RelaxngAttribute) opt.Patterns [0];
					}
					InferMergedAttribute (a);
				}
				RelaxngRef r = new RelaxngRef ();
				r.Name = attr.Name;
				p = r;
			} else {
				// local attribute
				RelaxngAttribute a = new RelaxngAttribute ();
				a.NameClass = new RelaxngName (
					attrName.Name, attrName.Namespace);
				a.Pattern = CreateSimplePattern (
					InferSimpleType (source.Value));
				p = a;
			}
			// optional
			if (laxOccurence ||
				(!isNewTypeDefinition && !mergedRequired)) {
				RelaxngOptional opt = new RelaxngOptional ();
				opt.Patterns.Add (p);
				p = opt;
			}

			return p;
		}
		private void InferElement (RelaxngRef r, bool isNew)
		{
			RelaxngDefine body = GetDefine (r.Name);
			InferElement (body, isNew);
		}
		private void Run ()
		{
			// move to top-level element
			source.MoveToContent ();
			int depth = source.Depth;
			if (source.NodeType != XmlNodeType.Element)
				throw new ArgumentException ("Argument XmlReader content is expected to be an element.");

			QName qname = new QName (source.LocalName,
				source.NamespaceURI);
			RelaxngDefine el = GetGlobalElement (qname);
			if (el == null) {
				el = CreateGlobalElement (qname);
				InferElement (el, true);
			}
			else
				InferElement (el, false);
			RelaxngStart start = new RelaxngStart ();
			start.Combine = "choice";
			RelaxngRef topRef = new RelaxngRef ();
			topRef.Name = el.Name;
			start.Pattern = topRef;
			grammar.Starts.Add (start);
		}