2011-06-15 72 views
10

這是相同的問題: Explicit Element Closing Tags with System.Xml.Linq Namespace如何強制使用Linq XML顯式標記關閉?

但我使用Net 4.0和答案不再工作。

問題是我保存的標籤,沒有價值真的,我的輸出XML是這樣的:

<field/>

但我需要的是始終在打開和關閉標籤,即

<field></field>

問題:怎麼辦?

編輯

添加空節點:

if (field_xml == null) // always true, because I create the file for the first time 
{ 
    field_xml = new XElement(XMLKeys.field,String.Empty); 
    table_xml.Add(field_xml); 
} 
field_xml.SetAttributeValue(XMLKeys.name, field_info.Name); 
// ... setting some other attributes of this node 

後來,保存XML:

var writer = new FullEndingXmlTextWriter(parameters.OutputFilename, Encoding.UTF8); 
root_xml.Save(writer); 

FullEndingXmlTextWriter是專業類的邪惡Greebo指出(它應該強制顯式結束標記)。

+0

爲什麼這很重要? – 2011-06-15 08:51:25

+0

@Dan軟件「吃」這可能是小錯誤,並沒有正確處理這個語法,我也一直處於這種情況。一般來說,這不重要。 – 2011-06-15 09:40:22

回答

4

我無法重現您的錯誤。這將按預期在這兩個4.0和3.5 NETFX:

namespace ExplicitXmlClosingTags 
{ 
    using System.Xml; 
    using System.Xml.Linq; 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      const string ElementRoot = "RootElement"; 
      const string ElementChild = "ChildElement"; 
      const string AttributeChild = "ChildAttribute"; 

      XDocument xDoc = new XDocument(); 
      XElement root = new XElement(ElementRoot); 
      XElement child = new XElement(ElementChild, string.Empty); 
      root.Add(child); 

      child.SetAttributeValue(AttributeChild, "AttrValue"); 
      xDoc.Add(root); 

      XmlWriterSettings xws = new XmlWriterSettings(); 
      xws.Indent = true; 
      using (XmlWriter xw = XmlWriter.Create("out.xml", xws)) 
      { 
       xDoc.Save(xw);  
      } 
     } 
    } 
} 

產生以下內容:

<?xml version="1.0" encoding="utf-8"?> 
<RootElement> 
    <ChildElement ChildAttribute="AttrValue"></ChildElement> 
</RootElement> 
+0

(謝謝你的答案)。現在,這**很有趣。我複製和粘貼你的例子,我做**不**具有明確的結束標籤(我也試過。淨3.5)。 Geee,兼容性... – greenoldman 2011-06-17 06:02:04

2

設定的值XElementString.Empty

OR

設置IsEmpty屬性false不具有任何的子節點

foreach (XElement childElement in 
     from x in document.DescendantNodes().OfType<XElement>() 
     where x.IsEmpty 
     select x) 
    { 
     childElement.IsEmpty = false; 
    } 
+0

我做過了,這是上一篇文章的答案,但它不起作用。 – greenoldman 2011-06-15 08:57:18

+0

編輯答案以顯示另一種方法,將「IsEmpty」設置爲「false」。 – harryovers 2011-06-15 09:35:09

+1

你編譯了這段代碼嗎?因爲在這裏我得到了錯誤信息,所以IsEmpty是隻讀屬性。好奇你是怎樣使它:-) – greenoldman 2011-06-16 05:38:22

8

XElement值明確設置爲空的所有元素字符串應該工作。正如您從XElement.IsEmpty的文檔中看到的,LINQ到XML已經將節點沒有內容(如new XElement("foo"))視爲與長度爲零的節點(如new XElement("foo", string.Empty))不同。

但在不工作的情況下,或者如果你需要微調XML輸出的一些其他方面,你可以得到一個定製XmlWriter

public class MyWriter : XmlWriter 
{ 
    private readonly XmlWriter inner; 
    public MyWriter(XmlWriter inner) 
    { 
     this.inner = inner; 
    } 

    public void Dispose() 
    { 
     ((IDisposable) inner).Dispose(); 
    } 

    public override void WriteStartDocument() 
    { 
     inner.WriteStartDocument(); 
    } 

    public override void WriteStartDocument(bool standalone) 
    { 
     inner.WriteStartDocument(standalone); 
    } 

    public override void WriteEndDocument() 
    { 
     inner.WriteEndDocument(); 
    } 

    public override void WriteDocType(string name, string pubid, string sysid, string subset) 
    { 
     inner.WriteDocType(name, pubid, sysid, subset); 
    } 

    public override void WriteStartElement(string prefix, string localName, string ns) 
    { 
     inner.WriteStartElement(prefix, localName, ns); 
    } 

    public override void WriteEndElement() 
    { 
     inner.WriteFullEndElement(); 
    } 

    public override void WriteFullEndElement() 
    { 
     inner.WriteFullEndElement(); 
    } 

    public override void WriteStartAttribute(string prefix, string localName, string ns) 
    { 
     inner.WriteStartAttribute(prefix, localName, ns); 
    } 

    public override void WriteEndAttribute() 
    { 
     inner.WriteEndAttribute(); 
    } 

    public override void WriteCData(string text) 
    { 
     inner.WriteCData(text); 
    } 

    public override void WriteComment(string text) 
    { 
     inner.WriteComment(text); 
    } 

    public override void WriteProcessingInstruction(string name, string text) 
    { 
     inner.WriteProcessingInstruction(name, text); 
    } 

    public override void WriteEntityRef(string name) 
    { 
     inner.WriteEntityRef(name); 
    } 

    public override void WriteCharEntity(char ch) 
    { 
     inner.WriteCharEntity(ch); 
    } 

    public override void WriteWhitespace(string ws) 
    { 
     inner.WriteWhitespace(ws); 
    } 

    public override void WriteString(string text) 
    { 
     inner.WriteString(text); 
    } 

    public override void WriteSurrogateCharEntity(char lowChar, char highChar) 
    { 
     inner.WriteSurrogateCharEntity(lowChar, highChar); 
    } 

    public override void WriteChars(char[] buffer, int index, int count) 
    { 
     inner.WriteChars(buffer, index, count); 
    } 

    public override void WriteRaw(char[] buffer, int index, int count) 
    { 
     inner.WriteRaw(buffer, index, count); 
    } 

    public override void WriteRaw(string data) 
    { 
     inner.WriteRaw(data); 
    } 

    public override void WriteBase64(byte[] buffer, int index, int count) 
    { 
     inner.WriteBase64(buffer, index, count); 
    } 

    public override void Close() 
    { 
     inner.Close(); 
    } 

    public override void Flush() 
    { 
     inner.Flush(); 
    } 

    public override string LookupPrefix(string ns) 
    { 
     return inner.LookupPrefix(ns); 
    } 

    public override WriteState WriteState 
    { 
     get { return inner.WriteState; } 
    } 
} 

相關的方法是這樣的一種:

public override void WriteEndElement() 
{ 
    inner.WriteFullEndElement(); // always write both start and close tags 
} 
+0

類似的例子在這裏談論:http://stackoverflow.com/questions/1849214/render-empty-xml-elements-as-parent-elements我有同樣的問題 - 我有一個黑盒子應用程序,需要完整的形成的XML和使用修改後的XmlWriter工作得非常好,以確保永遠不會發送簽約空標籤。 – 2011-06-15 09:57:32

+0

謝謝你的想法(順便說一句你的代碼是正確寫入 - 在你繼承和撰寫的XmlWriter的同時,其實你應該繼承,只覆蓋構造函數和相關方法),但是...我一些倒黴的傢伙,它仍然無法按預期工作。我在原始帖子中添加了一個編輯。 – greenoldman 2011-06-16 06:23:14

+0

@macias:繼承+構成是故意的。我寫的MyWriter是一個[裝飾器](http://en.wikipedia.org/wiki/Decorator_pattern)。它適用於任何XmlWriter,而不僅僅是XmlTextWriter。我完全按照原樣對它進行了測試,並且工作正常。我編寫了一個現有的XmlWriter實現,並繼承了相同的接口。 – 2011-06-16 09:12:20

-1
var document = XDocument.Parse(XMLData); 
         foreach (XElement childElement in 
         from x in document.DescendantNodes().OfType<XElement>() 
         where x.IsEmpty 
         select x) 
         { 
          childElement.Value = ""; 
         } 

試試這個工作。只需將childElement.IsEmpty = false;替換爲childElement.Value = "";