提交修改
This commit is contained in:
@@ -1,485 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FairyGUI.Utils
|
||||
{
|
||||
public enum XMLTagType
|
||||
{
|
||||
Start,
|
||||
End,
|
||||
Void,
|
||||
CDATA,
|
||||
Comment,
|
||||
Instruction
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class XMLIterator
|
||||
{
|
||||
public static string tagName;
|
||||
public static XMLTagType tagType;
|
||||
public static string lastTagName;
|
||||
|
||||
static string source;
|
||||
static int sourceLen;
|
||||
static int parsePos;
|
||||
static int tagPos;
|
||||
static int tagLength;
|
||||
static int lastTagEnd;
|
||||
static bool attrParsed;
|
||||
static bool lowerCaseName;
|
||||
static StringBuilder buffer = new StringBuilder();
|
||||
static Dictionary<string, string> attributes = new Dictionary<string, string>();
|
||||
|
||||
const string CDATA_START = "<![CDATA[";
|
||||
const string CDATA_END = "]]>";
|
||||
const string COMMENT_START = "<!--";
|
||||
const string COMMENT_END = "-->";
|
||||
|
||||
public static void Begin(string source, bool lowerCaseName = false)
|
||||
{
|
||||
XMLIterator.source = source;
|
||||
XMLIterator.lowerCaseName = lowerCaseName;
|
||||
sourceLen = source.Length;
|
||||
parsePos = 0;
|
||||
lastTagEnd = 0;
|
||||
tagPos = 0;
|
||||
tagLength = 0;
|
||||
tagName = null;
|
||||
}
|
||||
|
||||
public static bool NextTag()
|
||||
{
|
||||
int pos;
|
||||
char c;
|
||||
tagType = XMLTagType.Start;
|
||||
buffer.Length = 0;
|
||||
lastTagEnd = parsePos;
|
||||
attrParsed = false;
|
||||
lastTagName = tagName;
|
||||
|
||||
while ((pos = source.IndexOf('<', parsePos)) != -1)
|
||||
{
|
||||
parsePos = pos;
|
||||
pos++;
|
||||
|
||||
if (pos == sourceLen)
|
||||
break;
|
||||
|
||||
c = source[pos];
|
||||
if (c == '!')
|
||||
{
|
||||
if (sourceLen > pos + 7 && source.Substring(pos - 1, 9) == CDATA_START)
|
||||
{
|
||||
pos = source.IndexOf(CDATA_END, pos);
|
||||
tagType = XMLTagType.CDATA;
|
||||
tagName = string.Empty;
|
||||
tagPos = parsePos;
|
||||
if (pos == -1)
|
||||
tagLength = sourceLen - parsePos;
|
||||
else
|
||||
tagLength = pos + 3 - parsePos;
|
||||
parsePos += tagLength;
|
||||
return true;
|
||||
}
|
||||
else if (sourceLen > pos + 2 && source.Substring(pos - 1, 4) == COMMENT_START)
|
||||
{
|
||||
pos = source.IndexOf(COMMENT_END, pos);
|
||||
tagType = XMLTagType.Comment;
|
||||
tagName = string.Empty;
|
||||
tagPos = parsePos;
|
||||
if (pos == -1)
|
||||
tagLength = sourceLen - parsePos;
|
||||
else
|
||||
tagLength = pos + 3 - parsePos;
|
||||
parsePos += tagLength;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos++;
|
||||
tagType = XMLTagType.Instruction;
|
||||
}
|
||||
}
|
||||
else if (c == '/')
|
||||
{
|
||||
pos++;
|
||||
tagType = XMLTagType.End;
|
||||
}
|
||||
else if (c == '?')
|
||||
{
|
||||
pos++;
|
||||
tagType = XMLTagType.Instruction;
|
||||
}
|
||||
|
||||
for (; pos < sourceLen; pos++)
|
||||
{
|
||||
c = source[pos];
|
||||
if (Char.IsWhiteSpace(c) || c == '>' || c == '/')
|
||||
break;
|
||||
}
|
||||
if (pos == sourceLen)
|
||||
break;
|
||||
|
||||
buffer.Append(source, parsePos + 1, pos - parsePos - 1);
|
||||
if (buffer.Length > 0 && buffer[0] == '/')
|
||||
buffer.Remove(0, 1);
|
||||
|
||||
bool singleQuoted = false, doubleQuoted = false;
|
||||
int possibleEnd = -1;
|
||||
for (; pos < sourceLen; pos++)
|
||||
{
|
||||
c = source[pos];
|
||||
if (c == '"')
|
||||
{
|
||||
if (!singleQuoted)
|
||||
doubleQuoted = !doubleQuoted;
|
||||
}
|
||||
else if (c == '\'')
|
||||
{
|
||||
if (!doubleQuoted)
|
||||
singleQuoted = !singleQuoted;
|
||||
}
|
||||
|
||||
if (c == '>')
|
||||
{
|
||||
if (!(singleQuoted || doubleQuoted))
|
||||
{
|
||||
possibleEnd = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
possibleEnd = pos;
|
||||
}
|
||||
else if (c == '<')
|
||||
break;
|
||||
}
|
||||
if (possibleEnd != -1)
|
||||
pos = possibleEnd;
|
||||
|
||||
if (pos == sourceLen)
|
||||
break;
|
||||
|
||||
if (source[pos - 1] == '/')
|
||||
tagType = XMLTagType.Void;
|
||||
|
||||
tagName = buffer.ToString();
|
||||
if (lowerCaseName)
|
||||
tagName = tagName.ToLower();
|
||||
tagPos = parsePos;
|
||||
tagLength = pos + 1 - parsePos;
|
||||
parsePos += tagLength;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
tagPos = sourceLen;
|
||||
tagLength = 0;
|
||||
tagName = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string GetTagSource()
|
||||
{
|
||||
return source.Substring(tagPos, tagLength);
|
||||
}
|
||||
|
||||
public static string GetRawText(bool trim = false)
|
||||
{
|
||||
if (lastTagEnd == tagPos)
|
||||
return string.Empty;
|
||||
else if (trim)
|
||||
{
|
||||
int i = lastTagEnd;
|
||||
for (; i < tagPos; i++)
|
||||
{
|
||||
char c = source[i];
|
||||
if (!char.IsWhiteSpace(c))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == tagPos)
|
||||
return string.Empty;
|
||||
else
|
||||
return source.Substring(i, tagPos - i).TrimEnd();
|
||||
}
|
||||
else
|
||||
return source.Substring(lastTagEnd, tagPos - lastTagEnd);
|
||||
}
|
||||
|
||||
public static string GetText(bool trim = false)
|
||||
{
|
||||
if (lastTagEnd == tagPos)
|
||||
return string.Empty;
|
||||
else if (trim)
|
||||
{
|
||||
int i = lastTagEnd;
|
||||
for (; i < tagPos; i++)
|
||||
{
|
||||
char c = source[i];
|
||||
if (!char.IsWhiteSpace(c))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == tagPos)
|
||||
return string.Empty;
|
||||
else
|
||||
return XMLUtils.DecodeString(source.Substring(i, tagPos - i).TrimEnd());
|
||||
}
|
||||
else
|
||||
return XMLUtils.DecodeString(source.Substring(lastTagEnd, tagPos - lastTagEnd));
|
||||
}
|
||||
|
||||
public static bool HasAttribute(string attrName)
|
||||
{
|
||||
if (!attrParsed)
|
||||
{
|
||||
attributes.Clear();
|
||||
ParseAttributes(attributes);
|
||||
attrParsed = true;
|
||||
}
|
||||
|
||||
return attributes.ContainsKey(attrName);
|
||||
}
|
||||
|
||||
public static string GetAttribute(string attrName)
|
||||
{
|
||||
if (!attrParsed)
|
||||
{
|
||||
attributes.Clear();
|
||||
ParseAttributes(attributes);
|
||||
attrParsed = true;
|
||||
}
|
||||
|
||||
string value;
|
||||
if (attributes.TryGetValue(attrName, out value))
|
||||
return value;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string GetAttribute(string attrName, string defValue)
|
||||
{
|
||||
string ret = GetAttribute(attrName);
|
||||
if (ret != null)
|
||||
return ret;
|
||||
else
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static int GetAttributeInt(string attrName)
|
||||
{
|
||||
return GetAttributeInt(attrName, 0);
|
||||
}
|
||||
|
||||
public static int GetAttributeInt(string attrName, int defValue)
|
||||
{
|
||||
string value = GetAttribute(attrName);
|
||||
if (value == null || value.Length == 0)
|
||||
return defValue;
|
||||
|
||||
int ret;
|
||||
if (int.TryParse(value, out ret))
|
||||
return ret;
|
||||
else
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static float GetAttributeFloat(string attrName)
|
||||
{
|
||||
return GetAttributeFloat(attrName, 0);
|
||||
}
|
||||
|
||||
public static float GetAttributeFloat(string attrName, float defValue)
|
||||
{
|
||||
string value = GetAttribute(attrName);
|
||||
if (value == null || value.Length == 0)
|
||||
return defValue;
|
||||
|
||||
float ret;
|
||||
if (float.TryParse(value, out ret))
|
||||
return ret;
|
||||
else
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static bool GetAttributeBool(string attrName)
|
||||
{
|
||||
return GetAttributeBool(attrName, false);
|
||||
}
|
||||
|
||||
public static bool GetAttributeBool(string attrName, bool defValue)
|
||||
{
|
||||
string value = GetAttribute(attrName);
|
||||
if (value == null || value.Length == 0)
|
||||
return defValue;
|
||||
|
||||
bool ret;
|
||||
if (bool.TryParse(value, out ret))
|
||||
return ret;
|
||||
else
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static Dictionary<string, string> GetAttributes(Dictionary<string, string> result)
|
||||
{
|
||||
if (result == null)
|
||||
result = new Dictionary<string, string>();
|
||||
|
||||
if (attrParsed)
|
||||
{
|
||||
foreach (KeyValuePair<string, string> kv in attributes)
|
||||
result[kv.Key] = kv.Value;
|
||||
}
|
||||
else //这里没有先ParseAttributes再赋值给result是为了节省复制的操作
|
||||
ParseAttributes(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Hashtable GetAttributes(Hashtable result)
|
||||
{
|
||||
if (result == null)
|
||||
result = new Hashtable();
|
||||
|
||||
if (attrParsed)
|
||||
{
|
||||
foreach (KeyValuePair<string, string> kv in attributes)
|
||||
result[kv.Key] = kv.Value;
|
||||
}
|
||||
else //这里没有先ParseAttributes再赋值给result是为了节省复制的操作
|
||||
ParseAttributes(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ParseAttributes(IDictionary attrs)
|
||||
{
|
||||
string attrName;
|
||||
int valueStart;
|
||||
int valueEnd;
|
||||
bool waitValue = false;
|
||||
int quoted;
|
||||
buffer.Length = 0;
|
||||
int i = tagPos;
|
||||
int attrEnd = tagPos + tagLength;
|
||||
|
||||
if (i < attrEnd && source[i] == '<')
|
||||
{
|
||||
for (; i < attrEnd; i++)
|
||||
{
|
||||
char c = source[i];
|
||||
if (Char.IsWhiteSpace(c) || c == '>' || c == '/')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < attrEnd; i++)
|
||||
{
|
||||
char c = source[i];
|
||||
if (c == '=')
|
||||
{
|
||||
valueStart = -1;
|
||||
valueEnd = -1;
|
||||
quoted = 0;
|
||||
for (int j = i + 1; j < attrEnd; j++)
|
||||
{
|
||||
char c2 = source[j];
|
||||
if (Char.IsWhiteSpace(c2))
|
||||
{
|
||||
if (valueStart != -1 && quoted == 0)
|
||||
{
|
||||
valueEnd = j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (c2 == '>')
|
||||
{
|
||||
if (quoted == 0)
|
||||
{
|
||||
valueEnd = j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (c2 == '"')
|
||||
{
|
||||
if (valueStart != -1)
|
||||
{
|
||||
if (quoted != 1)
|
||||
{
|
||||
valueEnd = j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
quoted = 2;
|
||||
valueStart = j + 1;
|
||||
}
|
||||
}
|
||||
else if (c2 == '\'')
|
||||
{
|
||||
if (valueStart != -1)
|
||||
{
|
||||
if (quoted != 2)
|
||||
{
|
||||
valueEnd = j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
quoted = 1;
|
||||
valueStart = j + 1;
|
||||
}
|
||||
}
|
||||
else if (valueStart == -1)
|
||||
{
|
||||
valueStart = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (valueStart != -1 && valueEnd != -1)
|
||||
{
|
||||
attrName = buffer.ToString();
|
||||
if (lowerCaseName)
|
||||
attrName = attrName.ToLower();
|
||||
buffer.Length = 0;
|
||||
attrs[attrName] = XMLUtils.DecodeString(source.Substring(valueStart, valueEnd - valueStart + 1));
|
||||
i = valueEnd + 1;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
else if (!Char.IsWhiteSpace(c))
|
||||
{
|
||||
if (waitValue || c == '/' || c == '>')
|
||||
{
|
||||
if (buffer.Length > 0)
|
||||
{
|
||||
attrName = buffer.ToString();
|
||||
if (lowerCaseName)
|
||||
attrName = attrName.ToLower();
|
||||
attrs[attrName] = string.Empty;
|
||||
buffer.Length = 0;
|
||||
}
|
||||
|
||||
waitValue = false;
|
||||
}
|
||||
|
||||
if (c != '/' && c != '>')
|
||||
buffer.Append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buffer.Length > 0)
|
||||
waitValue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user