XmlWriter - 读取属性(快速问题)

发布于 2024-09-13 02:03:21 字数 3114 浏览 3 评论 0原文

我在我的代码中使用它,它完美地输出到 xml 文件,但它在元素名称后面添加了一个“=”符号,即使我的只有一个元素具有属性。

我想我可以做类似的事情

if(reader.Getattribute != "")
// I made that up on the spot, I'm not sure if that would really work
{
      Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
}

else
{
      Console.WriteLine("<{0}>", reader.Name);
}

,但是有没有更干净的方法来编码?

我的代码(没有解决方法)

using System;
using System.Xml;
using System.IO;
using System.Text;

public class MainClass
{
    private static void Main()
    {
        XmlWriterSettings settings = new XmlWriterSettings();

        settings.Indent = true;


        XmlWriter w = XmlWriter.Create(@"Path\test.xml", settings);



        w.WriteStartDocument();
        w.WriteStartElement("classes");

        w.WriteStartElement("class");
        w.WriteAttributeString("name", "EE 999");
        w.WriteElementString("Class_Name", "Programming");
        w.WriteElementString("Teacher", "James");
        w.WriteElementString("Room_Number", "333");
        w.WriteElementString("ID", "2324324");
        w.WriteEndElement();




        w.WriteEndDocument();
        w.Flush();
        w.Close();




        XmlReader reader = XmlReader.Create(@"Path\test.xml");

        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
                    break;
                case XmlNodeType.Text:
                    Console.WriteLine(reader.Value);
                    break;
                case XmlNodeType.CDATA:
                    Console.WriteLine("<[CDATA[{0}]>", reader.Value);
                    break;
                case XmlNodeType.ProcessingInstruction:
                    Console.WriteLine("<?{0} {1}?>", reader.Name, reader.Value);
                    break;
                case XmlNodeType.Comment:
                    Console.WriteLine("<!--{0}-->", reader.Value);
                    break;
                case XmlNodeType.XmlDeclaration:
                    Console.WriteLine("<?xml version='1.0'?>");
                    break;
                case XmlNodeType.Document:
                    break;
                case XmlNodeType.DocumentType:
                    Console.WriteLine("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
                    break;
                case XmlNodeType.EntityReference:
                    Console.WriteLine(reader.Name);
                    break;
                case XmlNodeType.EndElement:
                    Console.WriteLine("</{0}>", reader.Name);
                    break;
            }
        }
    }
}

输出

<?xml version='1.0'?>
<classes = >
<class = EE 999>
<Class_Name = >
Programming
</Class_Name>
<Teacher = >
James
</Teacher>
<Room_Number = >
333
</Room_Number>
<ID = >
2324324
</ID>
</class>
</classes>

I'm using this for my code, it outputs to the xml file perfectly, but it adds an ' = ' sign after the element name even though only one of my elements has an attribute.

I suppose I could do something like

if(reader.Getattribute != "")
// I made that up on the spot, I'm not sure if that would really work
{
      Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
}

else
{
      Console.WriteLine("<{0}>", reader.Name);
}

but is there a cleaner way to code that?

My code (without workaround)

using System;
using System.Xml;
using System.IO;
using System.Text;

public class MainClass
{
    private static void Main()
    {
        XmlWriterSettings settings = new XmlWriterSettings();

        settings.Indent = true;


        XmlWriter w = XmlWriter.Create(@"Path\test.xml", settings);



        w.WriteStartDocument();
        w.WriteStartElement("classes");

        w.WriteStartElement("class");
        w.WriteAttributeString("name", "EE 999");
        w.WriteElementString("Class_Name", "Programming");
        w.WriteElementString("Teacher", "James");
        w.WriteElementString("Room_Number", "333");
        w.WriteElementString("ID", "2324324");
        w.WriteEndElement();




        w.WriteEndDocument();
        w.Flush();
        w.Close();




        XmlReader reader = XmlReader.Create(@"Path\test.xml");

        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
                    break;
                case XmlNodeType.Text:
                    Console.WriteLine(reader.Value);
                    break;
                case XmlNodeType.CDATA:
                    Console.WriteLine("<[CDATA[{0}]>", reader.Value);
                    break;
                case XmlNodeType.ProcessingInstruction:
                    Console.WriteLine("<?{0} {1}?>", reader.Name, reader.Value);
                    break;
                case XmlNodeType.Comment:
                    Console.WriteLine("<!--{0}-->", reader.Value);
                    break;
                case XmlNodeType.XmlDeclaration:
                    Console.WriteLine("<?xml version='1.0'?>");
                    break;
                case XmlNodeType.Document:
                    break;
                case XmlNodeType.DocumentType:
                    Console.WriteLine("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
                    break;
                case XmlNodeType.EntityReference:
                    Console.WriteLine(reader.Name);
                    break;
                case XmlNodeType.EndElement:
                    Console.WriteLine("</{0}>", reader.Name);
                    break;
            }
        }
    }
}

Output

<?xml version='1.0'?>
<classes = >
<class = EE 999>
<Class_Name = >
Programming
</Class_Name>
<Teacher = >
James
</Teacher>
<Room_Number = >
333
</Room_Number>
<ID = >
2324324
</ID>
</class>
</classes>

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

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

发布评论

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

评论(2

秋凉 2024-09-20 02:03:21

因为这一行

case XmlNodeType.Element:
       Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
       break;

总是写入'='而不进行检查。

粗略的修复:

case XmlNodeType.Element:
       Console.WriteLine("<{0}", reader.Name);
       if (reader.HasAttributes)
          // Write out attributes
       Console.WriteLine(">");
       break;

但是您为什么要使用 XmlReader?它很麻烦,并且仅在处理巨大的 Xml 流时才有用。

如果您的数据集不是>> 10 MB,然后看看 XDocument 或 XmlDocument

示例中的 XmlWriter 可以替换为(大致):

 // using System.Xml.Linq;

        var root = new XElement("classes",
            new XElement("class", new XAttribute("name", "EE 999"),
                new XElement("Class_Name", "Programming"),
                new XElement("Teacher", "James")
                ));

        root.Save(@"Path\test.xml");

     var doc = XDocument.Load(@"Path\test.xml");
     // doc is now an in-memory tree of XElement objects 
     // that you can navigate and query

这里是 简介

Because this line

case XmlNodeType.Element:
       Console.WriteLine("<{0} = {1}>", reader.Name, reader.GetAttribute("name"));
       break;

Always writes the '=' without checking.

A rough fix :

case XmlNodeType.Element:
       Console.WriteLine("<{0}", reader.Name);
       if (reader.HasAttributes)
          // Write out attributes
       Console.WriteLine(">");
       break;

But why are you using the XmlReader at all? It is cumbersome and only useful when dealing with huge Xml streams.

If your datasets are not >> 10 MB then take a look at XDocument or XmlDocument

The XmlWriter in your Example can be replaced by (rough approx):

 // using System.Xml.Linq;

        var root = new XElement("classes",
            new XElement("class", new XAttribute("name", "EE 999"),
                new XElement("Class_Name", "Programming"),
                new XElement("Teacher", "James")
                ));

        root.Save(@"Path\test.xml");

     var doc = XDocument.Load(@"Path\test.xml");
     // doc is now an in-memory tree of XElement objects 
     // that you can navigate and query

And here is an intro

不忘初心 2024-09-20 02:03:21

我不确切知道您想要完成什么,但就我个人而言,我会创建一个代表您的类元素的 .NET 类,并使用标识子元素的属性,然后使用 System.Xml.Serialization.XmlSerializer 从文件中写入或读取它。

下面是一个示例:

using System.Xml.Serialization;

public class MyClasses : List<MyClass>{}    

public class MyClass{
 public String Teacher{ get; set; }
}

void main(){
  MyClasses classList = new MyClasses();

  MyClass c = new MyClass();
  c.Teacher = "James";

  classList.Add(c);

  XmlSerializer serializer = new XmlSerializer(classList.GetType());
  serializer.Serialize(/*Put your stream here*/);
}

并且,在将设置流作为练习留给读者之后,blamo,您已经完成了将对象的 XML 表示形式输出到某个流的操作。流可以是文件、字符串等。抱歉,C# 很糟糕(如果它很糟糕的话),我每天都使用 VB.NET,所以语法和关键字可能有点不对劲。

更新
我添加了一些代码来展示如何序列化类的集合。如果节点的命名不正确,您可以将一些属性添加到类属性中,只需快速搜索一下它们即可。

再次更新
抱歉,当我们使用同一个词来表示两种不同的事物时,很难解释。假设您正在尝试代表一桶砖块。您将编写一个名为 Brick 的 C# 类和一个名为 Bucket 的 C# 类,该类继承自 List 您的 Brick > 将有一个名为 Color 的属性。然后,你可以用不同的颜色制作所有的砖块,并将你的砖块装满桶。然后,您将存储桶传递给序列化器,它会给您类似的信息:

<Bucket>    
  <Brick>  
    <Color>    
      blue     
    </Color>  
  </Brick>   
</Bucket> 

序列化器根据类的定义为您构建 XML,因此您不必担心细节。您可以在此处阅读有关它的更多信息此处

I don't know exactly what you're trying to accomplish but personally I would create a .NET class representing your class element with properties identifying the sub elements then use System.Xml.Serialization.XmlSerializer to write or read it from a file.

Here is an example:

using System.Xml.Serialization;

public class MyClasses : List<MyClass>{}    

public class MyClass{
 public String Teacher{ get; set; }
}

void main(){
  MyClasses classList = new MyClasses();

  MyClass c = new MyClass();
  c.Teacher = "James";

  classList.Add(c);

  XmlSerializer serializer = new XmlSerializer(classList.GetType());
  serializer.Serialize(/*Put your stream here*/);
}

And, after leaving setting up your stream as an exercise to the reader, blamo, you're done outputing an XML representation of your object to some stream. The stream could be a file, string, whatever. Sorry for nasty C# (if its nasty) I use VB.NET everyday so the syntax and keywords may be a little off.

Update
I added some code to show how to serialize a collection of the classes. If nodes aren't coming out named correctly there are attributes you can add to your class properties, just do a quick google for them.

Update again
Sorry, its hard to explain when we're using the same word to mean two different things. Lets say you're trying to represent a bucket of bricks. You would write a C# class called Brick and a C# class called Bucket that inherited from List<Brick> your Brick would have a property called Color. You would then make all your bricks with different colors and fill the bucket with your bricks. Then you would pass your bucket to the serializer and it would give you something like:

<Bucket>    
  <Brick>  
    <Color>    
      blue     
    </Color>  
  </Brick>   
</Bucket> 

The serializer builds the XML for you from the definitions of your classes so you don't have to worry about the details. You can read more about it here and here

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