XML Parser内存溢出

时间:2015-12-22 14:53:51

标签: c# xml xml-parsing

您好我尝试编写XML-Parser来导入新Projekt的配置文件。但是我得到了一个内存溢出功能,正常工作之前一直在工作。

mem溢出在" distance = getFirstMatchBetweenKeyword(interfaceText," Distance")期间出现;"在导入界面方法

这是Importer.class:

class Importer
{
    string path;
    List<Router> routerlist = new List<Router>();
    StreamReader sr;

    public Importer(string newPath)
    {
        path = newPath;
        sr = new StreamReader(path);
    }

    public List<Router> getConfig()
    {
        getNodes(loadFile());
        return routerlist;
    }

    string loadFile()
    {
        string temp;
        //StreamReader sr = new StreamReader(path);
        temp = sr.ReadToEnd().TrimEnd(' ');
        temp.TrimStart(' ');
        return temp;
    }

    void getNodes(string importText)
    {
        string nodetext = getFirstMatchBetweenKeyword(importText, "Nodelist");
        while (nodetext.Length > 0)
        {
            importNode(getFirstMatchBetweenKeyword(nodetext, "Node"));
            nodetext = delTextUntil(nodetext, "Node");
        }
    }

    void importNode(string nodeText) {
        Router rtr;
        Interface intr;
        string name;
        name = getFirstMatchBetweenKeyword(nodeText, "Name");
        rtr = new Router(name);
        while (nodeText.Length > 0)
        {
            intr = importInterface(getFirstMatchBetweenKeyword(nodeText, "Interface"));
            nodeText = delTextUntil(nodeText, "Interface");
            rtr.setInterface(intr.Interf, intr.Network, intr.Distance);
        }
        routerlist.Add(rtr);
    }

    Interface importInterface(string interfaceText)
    {
        Interface inter;
        string name;
        string network;
        string distance;

        name = getFirstMatchBetweenKeyword(interfaceText, "Interfacename");
        network = getFirstMatchBetweenKeyword(interfaceText, "Network");
        distance = getFirstMatchBetweenKeyword(interfaceText, "Distance");

        inter = new Interface(name, network, distance);

        return inter;
    }
    string getFirstMatchBetweenKeyword(string text, string keyword)
    {
        string starting = "<" + keyword + ">";
        string ending =  "</" + keyword + ">";

        char[] oldText;
        char[] start;
        char[] end;
        char[] newText;
        int helper = 0;
        int bufferindex = 0;
        bool startParse = false;
        bool endParse = false;

        oldText = text.ToCharArray();
        start = starting.ToCharArray();
        end = ending.ToCharArray();
        newText = new char[oldText.Length];

        string output;

        for (int i = 0; i < oldText.Length; i++ )
        {
            if (startParse)
            {
                if (endParse)
                {
                    int delcounter = end.Length;
                    for (int ii = 0 ; ii < delcounter; ii++)
                    {
                        newText[bufferindex] = ' ';
                        bufferindex--;
                    }
                    break;
                }
                else
                {
                    newText[bufferindex] = oldText[i];
                    bufferindex++;
                    if (oldText[i] == end[helper])
                    {
                        helper++;
                        if (helper == end.Length)
                        {
                            endParse = true;
                        }
                    }
                    else
                    {
                        helper = 0;
                    }
                }
            }
            else
            {
                if (oldText[i] == start[helper])
                {
                    helper++;
                    if(helper == start.Length){
                        startParse = true;
                        helper = 0;
                    }
                }
                else
                {
                    helper = 0;
                }
            }
        }
        output = new string(newText);
        return output.TrimEnd(' ');
    }
    string delTextUntil(string oldText, string keyword)
    {
        keyword = "</" + keyword + ">";
        char[] old = oldText.ToCharArray();
        char[] key = keyword.ToCharArray();

        int keyindex = 0;

        for (int i = 0; i < old.Length; i++)
        {
            old[i] = ' ';
            if (oldText[i] == keyword[keyindex])
            {
                keyindex++;
                if (keyindex == keyword.Length)
                {
                    break;
                }
            }
            else { 
                keyindex = 0; 
            }
        }
        keyword = new string(old);
        keyword.TrimStart(' ');
        return keyword;
    }
}

如果需要,以下是Interface和Router类的定义:

class Router {
    string name = "";
    List<Interface> nodeList = new List<Interface>();


    public Router(string newName)
    {
        name = newName;
    }

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public void setInterface(string newInterface, string newNetwork, string newDistance)
    {
        Interface rnetdis = new Interface(newInterface, newNetwork, newDistance);
        nodeList.Add(rnetdis);           
    }

    public List<Interface> getRouterInterfaces()
    {
        return nodeList;
    }

    public bool delNetwork(string networkName)
    {
        for (int i = 0; i < nodeList.Count(); i++)
        {
            if (nodeList[i].Network == networkName)
            {
                nodeList.RemoveAt(i);
                return true;
            }
        }
        return false; 
    }
}

class Interface { 
    string interf;
    string network;
    string distance;

    public Interface(string newInterf)
    {
        interf = newInterf;
    }

    public Interface(string newInterf, string newNetwork, string newDistance)
    {
        interf = newInterf;
        network = newNetwork;
        distance = newDistance;
    }

    public string Interf
    {
        set{
            interf = value;
        }
        get
        {
            return interf;
        }
    }

    public string Network
    {
        set
        {
            network = value;
        }
        get
        {
            return network;
        }
    }
    public string Distance
    {
        set
        {
            distance = value;
        }
        get
        {
            return distance;
        }
    }
}

我要解析的配置看起来像这样:

<Nodelist>
    <Node>
        <Name>r1</Name>
        <Interface>
            <Interfacename>inter1</Interfacename>
            <Network>5</Network>
            <Distance>50</Distance>
        </Interface>
        <Interface>
            <Interfacename>inter2</Interfacename>
            <Network>2</Network>
            <Distance>20</Distance>
        </Interface>
    </Node>
    <Node>
        <Name>r2</Name>
        <Interface>
            <Interfacename>inter1</Interfacename>
            <Network>5</Network>
            <Distance>50</Distance>
        </Interface>
    </Node>
    <Node>
        <Name>r3</Name>
        <Interface>
            <Interfacename>inter1</Interfacename>
            <Network>2</Network>
            <Distance>20</Distance>
        </Interface>
    </Node>
</Nodelist>
希望有人可以帮助我。

非常感谢,

克里斯

1 个答案:

答案 0 :(得分:1)

有很多理由不自己解析XML。 阅读这篇优秀的文章:http://elegantcode.com/2010/08/07/dont-parse-that-xml/