2010-08-04 81 views
1

我使用它作爲我的代碼,它完美地輸出到xml文件,但它在元素名稱後添加了'='符號,即使只有一個元素具有屬性。XmlWriter - 閱讀屬性(快速問題)

我想我可以做這樣的事情

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> 

回答

1

由於此線

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 

這裏是an intro

+0

我應該如何編輯該語句以包含檢查屬性是否存在的內容? – superlazyname 2010-08-04 18:39:37

+0

我不知道如何使用XDocument或XmlDocument,我只是選擇了讀/寫XML的方法,我知道最好。如果你有一個很好的教程,我會看看。這種方法看起來很麻煩。 – superlazyname 2010-08-04 18:52:11

+0

我想過使用它,但它使用了很多我不太熟悉的術語(var,foreach,in,from)。我想我可以稍後再看。 – superlazyname 2010-08-06 00:43:16

0

我不知道你想要完成什麼,但是我個人會創建一個.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,大功告成outputing你的對象的XML表示一些流。流可能是一個文件,字符串,不管。對不起,討厭的C#(如果它討厭的話)我每天都使用VB.NET,所以語法和關鍵字可能會有點偏離。

更新
我添加了一些代碼來顯示如何序列化一個類的集合。如果節點沒有正確命名,那麼可以將屬性添加到您的類屬性中,只需爲它們做一個快速的Google。

再次更新
對不起,它很難在我們使用同一個詞是指兩個不同的東西來解釋。可以說你正在試圖代表一桶磚。您將編寫一個名爲Brick的C#類和一個名爲Bucket的C#類,該類繼承自List<Brick>,您的Brick將擁有一個名爲Color的屬性。然後,你會用不同的顏色製作所有的磚塊,並用磚塊裝滿水桶。然後,您會在水桶傳遞到串行化,它會給你這樣的:

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

串行器構建XML爲您從類的定義,所以你不必擔心細節。您可以閱讀更多關於它的信息herehere

+0

我正在嘗試製作幾個節點(每個節點代表一個班級,即像學校一樣,而不是編程班),並且每個節點都有一些元素,例如教師姓名,房間號碼等。 I don看不出你的建議將數據組織成這種結構。 – superlazyname 2010-08-04 18:50:33

+0

您也可以創建一個表示您的「類」列表的類(想一想列表),並用您爲表示「類」的每個類實例填充它,然後將列表傳遞給序列化程序。它應該跟隨作爲根對象和它下面的一堆節點。 – Justin 2010-08-04 18:57:42

+0

<注意:術語> 當我說''class''時我指的是你在學校出席的一些活動。當我說 'class'時,我指的是編程類。 所以你說我應該創建一個包含所有「類」的類,並讓每個「類」成爲某個類的實例?什麼級別? 另外,序列化程序有什麼作用? – superlazyname 2010-08-04 19:08:18