XmlWriter - чтение атрибута (быстрый вопрос) - PullRequest
1 голос
/ 04 августа 2010

Я использую это для своего кода, он отлично выводится в 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>

Ответы [ 2 ]

1 голос
/ 04 августа 2010

Потому что эта строка

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 МБ, взгляните на 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

А вот и вступление

0 голосов
/ 04 августа 2010

Я не знаю точно, что вы пытаетесь выполнить, но лично я бы создал класс .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 каждый день, поэтому синтаксис и ключевые слова могут быть немного не в порядке.

Обновление
Я добавил код, чтобы показать, как сериализовать коллекцию классов.Если узлы не названы правильно, есть атрибуты, которые вы можете добавить к свойствам вашего класса, просто сделайте быстрый поиск в Google.

Обновите снова
Извините, сложнообъясните, когда мы используем одно и то же слово для обозначения двух разных вещей.Допустим, вы пытаетесь представить ведро кирпичей.Вы бы написали класс C # с именем Brick, а класс C # с именем Bucket, унаследованный от List<Brick> вашего Brick, будет иметь свойство с именем Color.Затем вы сделаете все свои кирпичи разных цветов и наполните ведро своими кирпичами.Затем вы передадите свое ведро в сериализатор, и оно даст вам что-то вроде:

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

Сериализатор создает для вас XML из определений ваших классов, так что вам не нужно беспокоиться о деталях,Вы можете прочитать больше об этом здесь и здесь

...