我正在尝试为单个XML块构建一个正则表达式解析器。
我知道人们会说Regex不是一个很好的xml计划,但是我正在使用流数据,我只需要知道是否已经广播了一个完整的xml块并且是否位于缓冲区中。
我正在尝试处理XML的开始和结束块之间的任何内容以及主块头的参数中的任何数据。
我的示例代码位于细分的正则表达式之下,如果有人有任何关于如何使其尽可能全面的输入,我将非常感激。
这是我为视觉辅助格式化的正则表达式。
我正在平衡组和组,并验证它们在表达式段的末尾不存在。
/*
^(?<TAG>[<]
(?![?])
(?<TAGNAME>[^\s/>]*)
)
(?<ParamData>
(
(\"
(?>
\\\"|
[^"]|
\"(?<quote>)|
\"(?<-quote>)
)*
(?(quote)(?!))
\"
)|
[^/>]
)*?
)
(?:
(?<HASCONTENT>[>])|
(?<-TAG>
(?<TAGEND>/[>])
)
)
(?(HASCONTENT)
(
(?<CONTENT>
(
(?<inTAG>[<]\<TAGNAME>)(?<-inTAG>/[>])?|
(?<-inTAG>[<]/\<TAGNAME>[>])|
([^<]+|[<](?![/]?\<TAGNAME>))
)*?
(?(inTAG)(?!))
)
)
(?<TAGEND>(?<-TAG>)[<]/\<TAGNAME>[>])
)
(?(TAG)(?!))
*/
在我的课程中,我希望返回任何Null对象意味着队列中没有xml块。
这是我正在使用的课程。
(我使用文字字符串(@“”)来限制转义要求,所有“字符都替换为”“以正确格式化。
public class XmlDataParser
{
// xmlObjectExpression defined below to limit code highlight errors
private Regex _xmlRegex;
private Regex xmlRegex
{
get
{
if (_xmlRegex == null)
{
_xmlRegex = new Regex(xmlObjectExpression);
}
return _xmlRegex;
}
}
private string backingStore = "";
public bool HasObject()
{
return (backingStore != null) && xmlRegex.IsMatch(backingStore);
}
public string GetObject()
{
string result = null;
if (HasObject())
{
lock (this)
{
Match obj = xmlRegex.Match(backingStore);
result = obj.Value;
backingStore = backingStore.Substring(result.Length);
}
}
return result;
}
public void AddData(byte[] bytes)
{
lock (this)
{
backingStore += System.Text.Encoding.Default.GetString(bytes);
}
}
private static string xmlObjectExpression = @"^(?<TAG>[<](?![?])(?<TAGNAME>[^\s/>]*))(?<ParamData>((\""(?>\\\""|[^""]|\""(?<quote>)|\""(?<-quote>))*(?(quote)(?!))\"")|[^/>])*?)(?:(?<HASCONTENT>[>])|(?<-TAG>(?<TAGEND>/[>])))(?(HASCONTENT)((?<CONTENT>((?<inTAG>[<]\<TAGNAME>)(?<-inTAG>/[>])?|(?<-inTAG>[<]/\<TAGNAME>[>])|([^<]+|[<](?![/]?\<TAGNAME>)))*?(?(inTAG)(?!))))(?<TAGEND>(?<-TAG>)[<]/\<TAGNAME>[>]))(?(TAG)(?!))";
}
答案 0 :(得分:4)
只需使用XmlReader
并将其作为TextReader
。要读取流,您需要将ConformanceLevel更改为Fragment。
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create(tr,settings))
{
while (reader.Read())
{
switch (reader.NodeType)
{
// this is from my code. You'll rewrite this part :
case XmlNodeType.Element:
if (t != null)
{
t.SetName(reader.Name);
}
else if (reader.Name == "event")
{
t = new Event1();
t.Name = reader.Name;
}
else if (reader.Name == "data")
{
t = new Data1();
t.Name = reader.Name;
}
else
{
throw new Exception("");
}
break;
case XmlNodeType.Text:
if (t != null)
{
t.SetValue(reader.Value);
}
break;
case XmlNodeType.XmlDeclaration:
case XmlNodeType.ProcessingInstruction:
break;
case XmlNodeType.Comment:
break;
case XmlNodeType.EndElement:
if (t != null)
{
if (t.Name == reader.Name)
{
t.Close();
t.Write(output);
t = null;
}
}
break;
case XmlNodeType.Whitespace:
break;
}
}
}