кодирование синтаксического анализатора байтов C # XML (для класса), способ определить, находится ли я в родительском или дочернем элементе - PullRequest
0 голосов
/ 25 мая 2011

Для моего класса программирования C # начального уровня мы по сути кодируем наш собственный анализатор XML (используя FileStream и ReadByte ())

У нас есть файл "test.xml", который идет ... (мой учитель использует контейнер взаимозаменяемо с родительским элементом и использует атрибут как дочерний элемент, он немного сбивает с толку тех из нас, кто немного знает xml, но его класс нацелен на тех, кто не знает xml)

<containers>

<container>
<attribute1>data for attribute1 of container1</attribute1>
<attribute2>data for attribute2 of container1</attribute2>
<attribute3>data for attribute3 of container1</attribute3>
</container>
///more containers with varying amounts of attributes
...
</containers>

Теперь в его примере парсера (который мы должны изучить и сделать нашу собственную версию, мы можем использовать его структуру, но он предпочитает, чтобы мы немного ее переключили) он использует константу

const string XMLCONTAINER = "container"

чтобы проверить, находимся ли мы в родительском элементе или мы обрабатываем дочерний элемент контейнера

if(!gInsideContainer) {

    if(String.Compare(gParseToken,XMLCONTAINER)==0) {
    Console.WriteLine("\n***** BEG OF CONTAINER\n");
    gInsideContainer=true;

    // save the offset of the beginning of the
    // container into the container object
    setAttribute("BEGPTR",gTagOffset.ToString());
 }

Мне кажется, что это плохой mojo, так как это означает, что я должен редактировать исходный код для каждого типа xml, который мы в конечном итоге обрабатываем, чтобы выяснить, находимся ли мы в родительском элементе или нет. Я пытаюсь подумать, учитывая код, который мы должны изучить, как я могу сделать более общую проверку, чтобы увидеть, нахожусь ли я в родительском элементе или я являюсь дочерним по отношению к родительскому элементу.

Я думаю о создании массива для хранения открывающих элементов или другой строковой переменной для хранения текущего открывающего родительского элемента, затем проверки его закрывающего элемента, но это может не сработать так, как я думаю о его реализации поймать начальный

<containers>

и установите insideContainer в значение true для остальной части синтаксического анализа (у вас логические ошибки, по крайней мере, я могу определить это перед кодированием, хе)

Мне не разрешено использовать какой-либо из классов синтаксического анализа .net XML (поскольку мы в основном переписываем его с меньшими функциональными возможностями и, возможно, с меньшей эффективностью, но это скорее опыт решения проблем и создания алгоритмов, к которым он стремится учить)

Любые предложения о том, как я мог бы реализовать мою идею? (и имейте в виду, программист начального уровня здесь, смеется)

Большое спасибо за любую помощь и совет!

1 Ответ

1 голос
/ 25 мая 2011

Более общий способ поместить ваш элемент в стек каждый раз, когда вы анализируете новый тег ввода и извлекаете верхний тег из стека при выходе.Если вам нужно узнать, какой у вас родительский тег, вы можете посмотреть на него.

Еще лучше было бы создать древовидную структуру, где каждый узел содержит список дочерних узлов, а каждый дочерний узел содержит ссылку на своего родителя,что-то вроде

public class Node
{
    public string Name {get; private set;}
    public List<Node> Children {get;set;}
    public Node Parent {get; private set}

    public int ElementDepth
    {
        get{ return Parent == null ? 1 : Parent.Depth + 1; }
    }

    public Node(string name, Node parent)
    {
        this.Name = name;
        this.Children = new List<Node>();
        this.Parent = parent;
    }

    public Node(byte[] xml, ref int startAt)
    {
        if(this.Depth == 2)
        {
            Console.WriteLine("In Container named \"" + this.Name +"\"");
        }
        /*  in this function:
         *  Get the tag name and either (recursively) create its children
         *  or return if it closes this tag
         */
    }
}

, тогда в основном все, что вам нужно сделать, это загрузить байты в память и вызвать Node(myArray, ref myIndexPointer), и это долго, если эта функция определена правильно, все готово.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...