编码 C# XML 字节解析器(用于类),一种判断我是在父元素还是子元素中的方法

发布于 2024-11-09 20:25:07 字数 1545 浏览 4 评论 0原文

对于我的入门级 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 对于其余的解析(是的,逻辑错误,至少我可以在编码之前发现这个错误,呵呵)

我不允许使用任何 .net XML 解析类,(因为我们'基本上用更少的功能重写它可能效率较低,但他的目标是教授解决问题和创建算法的经验)

关于我如何实施我的想法有什么建议吗? (请记住,这里是初级程序员,哈哈)

非常感谢您的帮助和建议!

For my entry level C# programming class, we're essentially coding our own XML parser (using FileStream and ReadByte() )

We've got a "test.xml" file, that goes...
(my teacher uses container interchangeably with parent element and uses attribute as the child element, he's a bit confusing to those of us that know a bit of xml, but his class is aimed at those that don't know any 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>

Now in his example parser (which we're supposed to study and do our own version of, we can use his structure but he prefers us to switch it up a bit) he uses a constant

const string XMLCONTAINER = "container"

to check if we're inside a parent element or if we're processing a child element of 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());
 }

That seems to me to be bad mojo, as it means I have to edit the source code with every type of xml we end up processing just to figure out if we're in a parent element or not. I'm trying to think, given the code we've got to study off of, how I can do a more generic check to see if I'm inside a parent element or if I'm in a child of a parent element.

I'm thinking about creating an array to hold opening elements, or another string variable to hold the current opening parent element, then checking for its closing element, but that might not work as the ways I'm thinking of implementing it would catch the initial

<containers>

and set insideContainer to be true for the rest of the parsing (yay logic errors, at least I can spot this one before coding,heh)

I'm not allowed to use any of the .net XML parsing class, (as we're basically rewriting it with less functionality and probably less efficiently, but it's more the experience in problem solving and creating algorithms that he's aiming to teach)

Any suggestions on how I could go about implementing my idea? (and keep in mind, beginning level programmer here,lol)

Thanks much for any help and advice!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

亽野灬性zι浪 2024-11-16 20:25:07

每次解析时将元素推入 堆栈 的更通用方法一个新的入口标签,并在退出时从堆栈中弹出顶部标签。如果您需要知道您的父标签是什么,您可以查看它。

更好的是创建一个树结构,其中每个节点都包含子节点列表,每个子节点都包含到其父节点的链接,就像

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) 并且只要该函数正确定义即可完成。

A more generic way to push your element into a stack each time you parse a new entry tag and pop the top tag from the stack when you exit. If you need to know what your parent tag is you can peek at it.

Better still would be to create a tree structure where each node contains list of child nodes and each child node contains a link to its parent, something like

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
         */
    }
}

then in main all you have to do is load the bytes into memory and call Node(myArray, ref myIndexPointer) and is long as that function is defined properly your done.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文