don't load a full xml doc when we just want a single forward parse

master
UbitUmarov 2020-06-04 02:37:18 +01:00
parent 301f28cfd4
commit 84a3ff37ab
1 changed files with 45 additions and 36 deletions

View File

@ -457,6 +457,7 @@ namespace OpenSim.Server.Base
return sb.ToString(); return sb.ToString();
} }
public static string BuildXmlResponse(Dictionary<string, object> data) public static string BuildXmlResponse(Dictionary<string, object> data)
{ {
XmlDocument doc = new XmlDocument(); XmlDocument doc = new XmlDocument();
@ -466,8 +467,7 @@ namespace OpenSim.Server.Base
doc.AppendChild(xmlnode); doc.AppendChild(xmlnode);
XmlElement rootElement = doc.CreateElement("", "ServerResponse", XmlElement rootElement = doc.CreateElement("", "ServerResponse","");
"");
doc.AppendChild(rootElement); doc.AppendChild(rootElement);
@ -506,53 +506,62 @@ namespace OpenSim.Server.Base
} }
} }
private static Dictionary<string, object> ScanXmlResponse(XmlReader xr)
{
Dictionary<string, object> ret = new Dictionary<string, object>();
xr.Read();
while (!xr.EOF && xr.NodeType != XmlNodeType.EndElement)
{
if (xr.IsStartElement())
{
string type = xr.GetAttribute("type");
if (type != "List")
{
if (xr.IsEmptyElement)
{
ret[XmlConvert.DecodeName(xr.Name)] = "";
xr.Read();
}
else
ret[XmlConvert.DecodeName(xr.Name)] = xr.ReadElementContentAsString();
}
else
{
string name = XmlConvert.DecodeName(xr.Name);
if (xr.IsEmptyElement)
ret[name] = new Dictionary<string, object>();
else
ret[name] = ScanXmlResponse(xr);
xr.Read();
}
}
else
xr.Read();
}
return ret;
}
public static Dictionary<string, object> ParseXmlResponse(string data) public static Dictionary<string, object> ParseXmlResponse(string data)
{ {
//m_log.DebugFormat("[XXX]: received xml string: {0}", data); //m_log.DebugFormat("[XXX]: received xml string: {0}", data);
Dictionary<string, object> ret = new Dictionary<string, object>();
XmlDocument doc = new XmlDocument();
try try
{ {
doc.LoadXml(data); XmlReaderSettings xset = new XmlReaderSettings() { IgnoreWhitespace = true, IgnoreComments = true, ConformanceLevel = ConformanceLevel.Fragment, CloseInput = true };
XmlNodeList rootL = doc.GetElementsByTagName("ServerResponse"); XmlParserContext xpc = new XmlParserContext(null, null, null, XmlSpace.None);
xpc.Encoding = Util.UTF8NoBomEncoding;
if (rootL.Count != 1) using (XmlReader xr = XmlReader.Create(new StringReader(data), xset, xpc))
return ret; {
if(!xr.ReadToFollowing("ServerResponse"))
XmlNode rootNode = rootL[0]; return new Dictionary<string, object>();
return ScanXmlResponse(xr);
ret = ParseElement(rootNode); }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[serverUtils.ParseXmlResponse]: failed error: {0} \n --- string: {1} - ",e.Message, data); m_log.DebugFormat("[serverUtils.ParseXmlResponse]: failed error: {0}\n --string:\n{1}\n", e.Message, data);
} }
return ret; return new Dictionary<string, object>();
}
private static Dictionary<string, object> ParseElement(XmlNode element)
{
Dictionary<string, object> ret = new Dictionary<string, object>();
XmlNodeList partL = element.ChildNodes;
foreach (XmlNode part in partL)
{
XmlNode type = part.Attributes.GetNamedItem("type");
if (type == null || type.Value != "List")
{
ret[XmlConvert.DecodeName(part.Name)] = part.InnerText;
}
else
{
ret[XmlConvert.DecodeName(part.Name)] = ParseElement(part);
}
}
return ret;
} }
public static IConfig GetConfig(string configFile, string configName) public static IConfig GetConfig(string configFile, string configName)