2011-06-07 58 views
14

出於某種原因,下面的代碼生成的XML不包含聲明:我的XDeclaration在哪裏?

 XDocument xDocument = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), 
      new XElement("project", 
       new XAttribute("number", project.ProjectNumber), 
       new XElement("store", 
        new XAttribute("number", project.StoreNumber) 
       ), 

       // User Element 
       new XElement("user", 
        new XAttribute("owner-id", project.OwnerID ?? 0), 
        new XElement("email", new XCData(project.OwnerEmail ?? "")), 
        new XElement("project-name", new XCData(project.ProjectName ?? "")) 
       ), 

       // Nested Project Element 
       new XElement("nested-project", 
        new XAttribute("version", new Version(1, 0)), 
        new XElement("project", 
         new XAttribute("version", new Version(1, 0)), 
         xProjectItems = new XElement("project-items") 
        ), 
        new XElement("price-per-part", project.PricePerPart), 
        new XElement("sheet-quantity", project.SheetQuantity), 
        new XElement("edge-length", project.EdgeLength), 
        new XElement("price", project.Price), 
        new XElement("status", project.Status), 
        xMaterialItems = new XElement("alternative-material-items"), 
        xProductItems = new XElement("project-product-items") 
       ) 
      ) 
     ); 

     String strXML = xDocument.ToString(); 

它之前生產的聲明。我錯過了明顯的東西嗎?

謝謝。

回答

23

當您使用XDocument.Save methods之一的XDeclaration將可用。例如:

var doc = new XDocument (
      new XDeclaration ("1.0", "utf-8", "yes"), 
      new XElement ("test", "data") 
     ); 

string path = Path.Combine(Path.GetTempPath(), "temp.xml"); 
doc.Save(path); 
Console.WriteLine(File.ReadAllText(path)); 

或者你可以使用這種方法:

var sw = new StringWriter(); 
doc.Save(sw); 
string result = sw.GetStringBuilder().ToString(); 
Console.WriteLine(result); 

編輯:注意一些方法將在UTF-8指定轉換爲UTF-16。如果你想強制它是UTF-8,你將不得不使用這種不同的方法:

using (var mem = new MemoryStream()) 
using (var writer = new XmlTextWriter(mem, System.Text.Encoding.UTF8)) 
{ 
    writer.Formatting = Formatting.Indented; 
    doc.WriteTo(writer); 
    writer.Flush(); 
    mem.Flush(); 
    mem.Seek(0, SeekOrigin.Begin); 
    using (var reader = new StreamReader(mem)) 
    { 
     var xml = reader.ReadToEnd(); 
     Console.WriteLine(xml); 
    } 
} 
+0

+1我應該在我的答案中使用了StringWriter。衛生署! =] – rsbarro 2011-06-07 18:55:40

+1

這是跛腳。不是你的解決方案(這很酷 - 我沒有意識到你可以用'StringWriter'來完成)。微軟會這樣做的跛腳。我沒有將這個XML保存到一個文件中,而是將它傳遞給一個流。 'XDocument'和'XElement'有什麼區別。我的意思是它們很相似,但應該有一些區別。如果有人不希望字符串中的聲明,那麼你可能只是這樣做:'xMyDocument.Root.ToString();' – Jordan 2011-06-07 19:06:31

+0

@Jordan我想的理由是,一個XDocument代表整個文檔,並且是的XElement片段的XML。儘管如此,它們非常相似。 – 2011-06-07 19:20:13

3

documentation沒有明確指出xDocument.ToString()將輸出XML聲明,只說:「返回縮進XML爲這個節點。「。

在我的測試中,我發現下面的方法將輸出聲明:

使用ToStringDeclaration屬性:

string strXML = string.Concat(xDocument.Declaration.ToString(), "\r\n", 
           xDocument.ToString()); 

或使用Save方法:

string strXml; 
using(var ms = new MemoryStream()) 
{ 
    xDocument.Save(ms); 
    ms.Position = 0; 
    using(var sr = new StreamReader(ms)) 
    { 
     strXml = sr.ReadToEnd(); 
    } 
} 
+0

注意:我認爲@Ahmad Mageed用'StringWriter'的方法是最好的選擇。同樣的想法,但比我的'Save'方法更短。 – rsbarro 2011-06-07 18:55:21

+0

+1。我想有一個更長的方法,如我的編輯所示,需要強制編碼時。 – 2011-06-07 19:17:19