2011-09-15 69 views
0

我正在遍歷一個使用XmlReader的大型XML文檔,並將其拼接成一個更小,更易於管理的XmlDocmuent。一路上,我覺得這很有趣的一個節點,以便將它移到我這樣做:XmlReader原樣返回節點

 targetDoc.LoadXml("<result></result>"); 
     // Some interesting code removed 
     using (XmlReader r = XmlReader.Create(file)) 
     { 
      while (r.Read()) 
      { 
       if (r.NodeType == XmlNodeType.Element) 
       { 
        if (r.Name == match) 
        { 
         // Put the node into the target document 
         targetDoc.FirstChild.InnerXml = r.ReadOuterXml(); 
         return targetDoc; 
        } 
       } 
      } 
     } 

這是一切都很好,但我想包括節點不及其後代。我感興趣的是節點本身及其屬性。在這一點上,後代非常龐大,體積龐大且無趣。 (並將它們一次讀入內存將導致內存不足錯誤...)

是否有一種簡單的方法來獲取找到的元素的文本(?)及其屬性 - 但不是它的後代 - 進入目標文件?

+1

你不應該使用'新的XmlTextReader()'。改用'XmlReader.Create()'。 –

+0

它實際上是作爲外部函數(未顯示)的參數傳遞併爲SO輸入的。有希望編輯,我會得到一個有用的答案。 –

+0

試圖幫助那些不知道比複製/粘貼他們在這裏看到的代碼更好的人。 –

回答

1

我不認爲有這樣做的內置方式。我想你必須自己讀出屬性和內容。

例如

static void Main(string[] args) 
     { 
      var xml = @"<root> 
           <parent a1 = 'foo' a2 = 'bar'>Some Parent text 
            <child a3 = 'frob' a2= 'brob'> Some Child Text 
            </child> 
           </parent> 
      </root>"; 
      var file = new StringReader(xml) ; 

      using (XmlReader r = XmlReader.Create(file)) 
      { 
       while (r.Read()) 
       { 
        if (r.NodeType == XmlNodeType.Element) 
        { 
         if (r.Name == "parent") 
         { 
          var output = new StringBuilder(); 
          var settings = new XmlWriterSettings(); 
          settings.OmitXmlDeclaration = true; 
          using (var elementWriter = XmlWriter.Create(output, settings)) 
          { 

           elementWriter.WriteStartElement(r.Name); 

           elementWriter.WriteAttributes(r,false); 
           elementWriter.WriteValue(r.ReadString()); 
           elementWriter.WriteEndElement(); 
          } 

          Console.WriteLine(output.ToString()); 
         } 
        } 
       } 
      } 


      if (System.Diagnostics.Debugger.IsAttached) 
       Console.ReadLine(); 

     } 

會產生

<parent a1="foo" a2="bar">Some Parent text</parent> 
Press any key to continue . . . 
+0

這看起來不錯。 –

0

您可以嘗試XmlNode.CloneNode(bool deep)方法。

deep:爲了遞歸地克隆指定節點下的子樹;假只克隆節點本身。

+0

他沒有XmlNode來克隆,因爲後代太龐大。 –

0

不一定是一個好方法,但是您可以讀取字符串,直到到達開始標記的末尾,然後手動追加一個結束標記並將其加載到XmlDocument中。

編輯:

思路是這樣的:

string xml = r.ReadOuterXml(); 
int firstEndTag = xml.IndexOf('>'); 
int lastStartTag = xml.LastIndexOf('<'); 
string newXml = xml.Substring(0, firstEndTag) + xml.Substring(lastStartTag); 

可言,因爲有一個大的字符串就在那裏,這可能是無效的。你的方式可能是最好的。兩者都不漂亮,但我個人不能想出更好的方法,因爲你的限制(這並不是說沒有更好的方法)。

+0

我想過類似於:if(r.HasAttributes) for(int i = 0; i }'然後按照您的建議重新構建節點的XML,但這看起來......很難看。 –

+0

@clintp編輯。 –