对于我的入门级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());
}
在我看来,这是糟糕的魔力,因为这意味着我必须使用每种类型的xml编辑源代码,我们最终处理它们才能弄清楚我们是否在父元素中。我正在考虑,考虑到我们必须研究的代码,如何进行更通用的检查,看看我是否在父元素内部,或者我是否在父元素的子元素中。
我正在考虑创建一个数组来保存开放元素,或者另一个字符串变量来保存当前打开的父元素,然后检查它的结束元素,但这可能不适合我想要实现它的方式会抓住最初的
<containers>
并将insideContainer设置为其余解析为true(yay逻辑错误,至少我可以在编码之前发现这个,呵呵)
我不允许使用任何.net XML解析类,(因为我们基本上用较少的功能重写它,可能效率较低,但它更多的是解决问题和创建算法的经验,他的目标是教导)
关于如何实施我的想法的任何建议? (并记住,在这里开始级程序员,哈哈)
非常感谢您的帮助和建议!
答案 0 :(得分:1)
每次解析新条目标记时将元素推送到stack的更通用的方法,并在退出时从堆栈中弹出顶部标记。如果你需要知道你的父标签是什么,你可以偷看它。
更好的是创建一个树结构,其中每个节点都包含子节点列表,每个子节点都包含指向其父节点的链接,如
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
*/
}
}
然后在main中你需要做的就是将字节加载到内存中并调用Node(myArray, ref myIndexPointer)
并且只要该函数被正确定义就完成了。