a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
517 lines
12 KiB
C#
517 lines
12 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Xml;
|
|
using Commons.Xml.Relaxng;
|
|
|
|
namespace Commons.Xml.Nvdl
|
|
{
|
|
public class NvdlReader
|
|
{
|
|
public static NvdlRules Read (XmlReader reader)
|
|
{
|
|
return new NvdlReader (reader).ReadRules ();
|
|
}
|
|
|
|
XmlReader reader;
|
|
IXmlLineInfo lineInfo;
|
|
XmlDocument doc = new XmlDocument ();
|
|
|
|
private NvdlReader (XmlReader reader)
|
|
{
|
|
// FIXME: use .rnc validation.
|
|
this.reader = reader;
|
|
this.lineInfo = reader as IXmlLineInfo;
|
|
reader.MoveToContent ();
|
|
}
|
|
|
|
private void FillForeignAttribute (NvdlAttributable el)
|
|
{
|
|
if (!reader.MoveToFirstAttribute ())
|
|
return;
|
|
do {
|
|
if (reader.NamespaceURI == "")
|
|
continue;
|
|
XmlAttribute a = doc.CreateAttribute (
|
|
reader.Prefix,
|
|
reader.LocalName,
|
|
reader.NamespaceURI);
|
|
a.Value = reader.Value;
|
|
el.Foreign.Add (a);
|
|
} while (reader.MoveToNextAttribute ());
|
|
reader.MoveToElement ();
|
|
}
|
|
|
|
private void FillNonXmlAttributes (NvdlMessage el)
|
|
{
|
|
if (!reader.MoveToFirstAttribute ())
|
|
return;
|
|
do {
|
|
if (reader.NamespaceURI == Nvdl.XmlNamespaceUri)
|
|
continue;
|
|
XmlAttribute a = doc.CreateAttribute (
|
|
reader.Prefix,
|
|
reader.LocalName,
|
|
reader.NamespaceURI);
|
|
a.Value = reader.Value;
|
|
el.ForeignAttributes.Add (a);
|
|
} while (reader.MoveToNextAttribute ());
|
|
reader.MoveToElement ();
|
|
}
|
|
|
|
private void FillLocation (NvdlElementBase el)
|
|
{
|
|
el.SourceUri = reader.BaseURI;
|
|
if (lineInfo != null) {
|
|
el.LineNumber = lineInfo.LineNumber;
|
|
el.LinePosition = lineInfo.LinePosition;
|
|
}
|
|
}
|
|
|
|
private NvdlRuleTarget ParseMatch (string s)
|
|
{
|
|
if (s == null)
|
|
return NvdlRuleTarget.None;
|
|
if (s.IndexOf ("elements") >= 0)
|
|
return (s.IndexOf ("attributes") >= 0) ?
|
|
NvdlRuleTarget.Both :
|
|
NvdlRuleTarget.Elements;
|
|
else
|
|
return (s.IndexOf ("attributes") >= 0) ?
|
|
NvdlRuleTarget.Attributes :
|
|
NvdlRuleTarget.None;
|
|
}
|
|
|
|
private NvdlRules ReadRules ()
|
|
{
|
|
NvdlRules el = new NvdlRules ();
|
|
FillLocation (el);
|
|
el.SchemaType = reader.GetAttribute ("schemaType");
|
|
el.StartMode = reader.GetAttribute ("startMode");
|
|
FillForeignAttribute (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
return el;
|
|
}
|
|
reader.Read ();
|
|
do {
|
|
reader.MoveToContent ();
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
break;
|
|
if (reader.NamespaceURI != Nvdl.Namespace) {
|
|
el.Foreign.Add (doc.ReadNode (reader));
|
|
continue;
|
|
}
|
|
switch (reader.LocalName) {
|
|
case "mode":
|
|
el.Modes.Add (ReadMode ());
|
|
break;
|
|
case "namespace":
|
|
el.Rules.Add (ReadNamespace ());
|
|
break;
|
|
case "anyNamespace":
|
|
el.Rules.Add (ReadAnyNamespace ());
|
|
break;
|
|
case "trigger":
|
|
el.Triggers.Add (ReadTrigger ());
|
|
break;
|
|
}
|
|
} while (!reader.EOF);
|
|
if (!reader.EOF)
|
|
reader.Read ();
|
|
return el;
|
|
}
|
|
|
|
private NvdlTrigger ReadTrigger ()
|
|
{
|
|
NvdlTrigger el = new NvdlTrigger ();
|
|
FillLocation (el);
|
|
el.NS = reader.GetAttribute ("ns");
|
|
el.NameList = reader.GetAttribute ("nameList");
|
|
FillForeignAttribute (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
return el;
|
|
}
|
|
reader.Read ();
|
|
do {
|
|
reader.MoveToContent ();
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
break;
|
|
if (reader.NamespaceURI != Nvdl.Namespace) {
|
|
el.Foreign.Add (doc.ReadNode (reader));
|
|
continue;
|
|
}
|
|
} while (!reader.EOF);
|
|
if (!reader.EOF)
|
|
reader.Read ();
|
|
return el;
|
|
}
|
|
|
|
private NvdlMode ReadMode ()
|
|
{
|
|
NvdlMode el = new NvdlMode ();
|
|
FillLocation (el);
|
|
el.Name = reader.GetAttribute ("name");
|
|
ReadModeCommon (el);
|
|
return el;
|
|
}
|
|
|
|
private NvdlIncludedMode ReadIncludedMode ()
|
|
{
|
|
NvdlIncludedMode el = new NvdlIncludedMode ();
|
|
FillLocation (el);
|
|
el.Name = reader.GetAttribute ("name");
|
|
ReadModeCommon (el);
|
|
return el;
|
|
}
|
|
|
|
private NvdlNestedMode ReadNestedMode ()
|
|
{
|
|
NvdlNestedMode el = new NvdlNestedMode ();
|
|
FillLocation (el);
|
|
ReadModeCommon (el);
|
|
return el;
|
|
}
|
|
|
|
private void ReadModeCommon (NvdlModeBase el)
|
|
{
|
|
FillForeignAttribute (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
return;
|
|
}
|
|
reader.Read ();
|
|
do {
|
|
reader.MoveToContent ();
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
break;
|
|
if (reader.NamespaceURI != Nvdl.Namespace) {
|
|
el.Foreign.Add (doc.ReadNode (reader));
|
|
continue;
|
|
}
|
|
switch (reader.LocalName) {
|
|
case "mode":
|
|
el.IncludedModes.Add (ReadIncludedMode ());
|
|
break;
|
|
case "namespace":
|
|
el.Rules.Add (ReadNamespace ());
|
|
break;
|
|
case "anyNamespace":
|
|
el.Rules.Add (ReadAnyNamespace ());
|
|
break;
|
|
}
|
|
} while (!reader.EOF);
|
|
if (!reader.EOF)
|
|
reader.Read ();
|
|
return;
|
|
}
|
|
|
|
private NvdlAnyNamespace ReadAnyNamespace ()
|
|
{
|
|
NvdlAnyNamespace el = new NvdlAnyNamespace ();
|
|
FillLocation (el);
|
|
el.Match = ParseMatch (reader.GetAttribute ("match"));
|
|
FillForeignAttribute (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
return el;
|
|
}
|
|
reader.Read ();
|
|
do {
|
|
reader.MoveToContent ();
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
break;
|
|
if (reader.NamespaceURI != Nvdl.Namespace) {
|
|
el.Foreign.Add (doc.ReadNode (reader));
|
|
continue;
|
|
}
|
|
ReadAction (el);
|
|
} while (!reader.EOF);
|
|
if (!reader.EOF)
|
|
reader.Read ();
|
|
return el;
|
|
}
|
|
|
|
private NvdlNamespace ReadNamespace ()
|
|
{
|
|
NvdlNamespace el = new NvdlNamespace ();
|
|
FillLocation (el);
|
|
el.NS = reader.GetAttribute ("ns");
|
|
el.Wildcard = reader.GetAttribute ("wildCard");
|
|
el.Match = ParseMatch (reader.GetAttribute ("match"));
|
|
FillForeignAttribute (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
return el;
|
|
}
|
|
reader.Read ();
|
|
do {
|
|
reader.MoveToContent ();
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
break;
|
|
if (reader.NamespaceURI != Nvdl.Namespace) {
|
|
el.Foreign.Add (doc.ReadNode (reader));
|
|
continue;
|
|
}
|
|
ReadAction (el);
|
|
} while (!reader.EOF);
|
|
if (!reader.EOF)
|
|
reader.Read ();
|
|
return el;
|
|
}
|
|
|
|
private void ReadAction (NvdlRule el)
|
|
{
|
|
switch (reader.LocalName) {
|
|
case "cancelNestedActions":
|
|
el.Actions.Add (ReadCancelAction ());
|
|
break;
|
|
case "validate":
|
|
el.Actions.Add (ReadValidate ());
|
|
break;
|
|
case "allow":
|
|
el.Actions.Add (ReadAllow ());
|
|
break;
|
|
case "reject":
|
|
el.Actions.Add (ReadReject ());
|
|
break;
|
|
case "attach":
|
|
el.Actions.Add (ReadAttach ());
|
|
break;
|
|
case "attachPlaceHolder":
|
|
el.Actions.Add (ReadAttachPlaceholder ());
|
|
break;
|
|
case "unwrap":
|
|
el.Actions.Add (ReadUnwrap ());
|
|
break;
|
|
default:
|
|
throw new NotSupportedException ();
|
|
}
|
|
}
|
|
|
|
private NvdlCancelAction ReadCancelAction ()
|
|
{
|
|
NvdlCancelAction el = new NvdlCancelAction ();
|
|
FillLocation (el);
|
|
FillForeignAttribute (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
return el;
|
|
}
|
|
reader.Read ();
|
|
do {
|
|
reader.MoveToContent ();
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
break;
|
|
if (reader.NamespaceURI != Nvdl.Namespace) {
|
|
el.Foreign.Add (doc.ReadNode (reader));
|
|
continue;
|
|
}
|
|
} while (!reader.EOF);
|
|
if (!reader.EOF)
|
|
reader.Read ();
|
|
return el;
|
|
}
|
|
|
|
private NvdlValidate ReadValidate ()
|
|
{
|
|
NvdlValidate el = new NvdlValidate ();
|
|
NvdlModeUsage mu = new NvdlModeUsage ();
|
|
el.ModeUsage = mu;
|
|
FillLocation (el);
|
|
el.SchemaType = reader.GetAttribute ("schemaType");
|
|
el.SimpleMessage = reader.GetAttribute ("message");
|
|
el.SchemaUri = reader.GetAttribute ("schema");
|
|
mu.UseMode = reader.GetAttribute ("useMode");
|
|
FillForeignAttribute (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
return el;
|
|
}
|
|
reader.Read ();
|
|
do {
|
|
reader.MoveToContent ();
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
break;
|
|
if (reader.NamespaceURI != Nvdl.Namespace) {
|
|
el.Foreign.Add (doc.ReadNode (reader));
|
|
continue;
|
|
}
|
|
switch (reader.LocalName) {
|
|
case "message":
|
|
el.Messages.Add (ReadMessage ());
|
|
break;
|
|
case "option":
|
|
el.Options.Add (ReadOption ());
|
|
break;
|
|
case "schema":
|
|
el.SchemaBody = (XmlElement) doc.ReadNode (reader);
|
|
break;
|
|
case "mode":
|
|
mu.NestedMode = ReadNestedMode ();
|
|
break;
|
|
case "context":
|
|
mu.Contexts.Add (ReadContext ());
|
|
break;
|
|
default:
|
|
throw new NotSupportedException ();
|
|
}
|
|
} while (!reader.EOF);
|
|
if (!reader.EOF)
|
|
reader.Read ();
|
|
return el;
|
|
}
|
|
|
|
private NvdlAllow ReadAllow ()
|
|
{
|
|
NvdlAllow el = new NvdlAllow ();
|
|
ReadCommonActionContent (el);
|
|
return el;
|
|
}
|
|
|
|
private NvdlReject ReadReject ()
|
|
{
|
|
NvdlReject el = new NvdlReject ();
|
|
ReadCommonActionContent (el);
|
|
return el;
|
|
}
|
|
|
|
private NvdlAttach ReadAttach ()
|
|
{
|
|
NvdlAttach el = new NvdlAttach ();
|
|
ReadCommonActionContent (el);
|
|
return el;
|
|
}
|
|
|
|
private NvdlAttachPlaceholder ReadAttachPlaceholder ()
|
|
{
|
|
NvdlAttachPlaceholder el = new NvdlAttachPlaceholder ();
|
|
ReadCommonActionContent (el);
|
|
return el;
|
|
}
|
|
|
|
private NvdlUnwrap ReadUnwrap ()
|
|
{
|
|
NvdlUnwrap el = new NvdlUnwrap ();
|
|
ReadCommonActionContent (el);
|
|
return el;
|
|
}
|
|
|
|
private void ReadCommonActionContent (NvdlNoCancelAction el)
|
|
{
|
|
FillLocation (el);
|
|
NvdlModeUsage mu = new NvdlModeUsage ();
|
|
el.ModeUsage = mu;
|
|
FillLocation (el);
|
|
el.SimpleMessage = reader.GetAttribute ("message");
|
|
mu.UseMode = reader.GetAttribute ("useMode");
|
|
FillForeignAttribute (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
return;
|
|
}
|
|
reader.Read ();
|
|
do {
|
|
reader.MoveToContent ();
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
break;
|
|
if (reader.NamespaceURI != Nvdl.Namespace) {
|
|
el.Foreign.Add (doc.ReadNode (reader));
|
|
continue;
|
|
}
|
|
switch (reader.LocalName) {
|
|
case "mode":
|
|
mu.NestedMode = ReadNestedMode ();
|
|
break;
|
|
case "message":
|
|
el.Messages.Add (ReadMessage ());
|
|
break;
|
|
case "context":
|
|
mu.Contexts.Add (ReadContext ());
|
|
break;
|
|
default:
|
|
throw new NotSupportedException ();
|
|
}
|
|
} while (!reader.EOF);
|
|
if (!reader.EOF)
|
|
reader.Read ();
|
|
}
|
|
|
|
private NvdlMessage ReadMessage ()
|
|
{
|
|
NvdlMessage el = new NvdlMessage ();
|
|
FillLocation (el);
|
|
el.XmlLang = reader.GetAttribute ("lang", Nvdl.XmlNamespaceUri);
|
|
FillNonXmlAttributes (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
el.Text = "";
|
|
}
|
|
else
|
|
el.Text = reader.ReadElementString ();
|
|
return el;
|
|
}
|
|
|
|
private NvdlOption ReadOption ()
|
|
{
|
|
NvdlOption el = new NvdlOption ();
|
|
FillLocation (el);
|
|
el.Name = reader.GetAttribute ("name");
|
|
el.Arg = reader.GetAttribute ("arg");
|
|
el.MustSupport = reader.GetAttribute ("mustSupport");
|
|
FillForeignAttribute (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
return el;
|
|
}
|
|
reader.Read ();
|
|
do {
|
|
reader.MoveToContent ();
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
break;
|
|
if (reader.NamespaceURI != Nvdl.Namespace) {
|
|
el.Foreign.Add (doc.ReadNode (reader));
|
|
continue;
|
|
}
|
|
} while (!reader.EOF);
|
|
if (!reader.EOF)
|
|
reader.Read ();
|
|
return el;
|
|
}
|
|
|
|
private NvdlContext ReadContext ()
|
|
{
|
|
NvdlContext el = new NvdlContext ();
|
|
FillLocation (el);
|
|
el.Path = reader.GetAttribute ("path");
|
|
el.UseMode = reader.GetAttribute ("useMode");
|
|
FillForeignAttribute (el);
|
|
if (reader.IsEmptyElement) {
|
|
reader.Skip ();
|
|
return el;
|
|
}
|
|
reader.Read ();
|
|
do {
|
|
reader.MoveToContent ();
|
|
if (reader.NodeType == XmlNodeType.EndElement)
|
|
break;
|
|
if (reader.NamespaceURI != Nvdl.Namespace) {
|
|
el.Foreign.Add (doc.ReadNode (reader));
|
|
continue;
|
|
}
|
|
switch (reader.LocalName) {
|
|
case "mode":
|
|
el.NestedMode = ReadNestedMode ();
|
|
break;
|
|
default:
|
|
throw new NotSupportedException ();
|
|
}
|
|
} while (!reader.EOF);
|
|
if (!reader.EOF)
|
|
reader.Read ();
|
|
return el;
|
|
}
|
|
}
|
|
}
|
|
|