2016-12-27 109 views
0

我的XML有問題。xml linq無法刪除元素

我需要刪除所有不在我的名單

,但它不是在dd標籤

在這裏工作的標籤是XML輸入

http://pastebin.com/J8KkkMDJ

這裏我的列表。這個名單是僅在XML

  lstApprove.Add("Styles"); 
      lstApprove.Add("alto"); 
      lstApprove.Add("Description"); 
      lstApprove.Add("MeasurementUnit"); 
      lstApprove.Add("sourceImageInformation"); 
      lstApprove.Add("fileName"); 
      lstApprove.Add("OCRProcessing"); 
      lstApprove.Add("preProcessingStep"); 
      lstApprove.Add("processingSoftware"); 
      lstApprove.Add("softwareCreator"); 
      lstApprove.Add("softwareName"); 
      lstApprove.Add("softwareVersion"); 
      lstApprove.Add("ocrProcessingStep"); 
      lstApprove.Add("ParagraphStyle"); 
      lstApprove.Add("Layout"); 
      lstApprove.Add("Page"); 
      lstApprove.Add("PrintSpace"); 
      lstApprove.Add("TextBlock"); 
      lstApprove.Add("TextLine"); 
      lstApprove.Add("String"); 
      lstApprove.Add("SP"); 
      lstApprove.Add("ComposedBlock"); 
      lstApprove.Add("GraphicalElement"); 

允許的,這裏是代碼去除不在列表

   using (StreamReader reader = new StreamReader(xmlFile)) 
       { 

        nAlto = reader.ReadToEnd(); 

        nAlto = nAlto.Replace("<document xmlns=\"http://www.scansoft.com/omnipage/xml/ssdoc-schema3.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">", "<document>"); 
        nAlto = nAlto.Replace("<?xml version=\"1.0\" encoding=\"UTF-16\"?>", ""); 
       } 


       XDocument doc = XDocument.Parse(nAlto); 
        foreach (var item in doc.Descendants().ToList()) 
        { 
         if (!lstApprove.Contains(item.Name.ToString())) 
         { 
          if (item.HasElements) 
          { 
           item.ReplaceWith(item.Elements()); 
          } 
          else 
          { 
           item.Remove(); 
          } 
         } 

        } 

上的標籤和這裏的標籤被輸出

http://pastebin.com/XjYBTWci

這是XML輸出的部分

<dd l="2342.29" t="133.12" r="2427.71" b="209.17"> 
      <TextBlock ID="P1_TB0000001" TAGREFS="LAYOUT_TAG_001" HPOS="2349.17" VPOS="160" WIDTH="71.66" HEIGHT="36.04" STYLEREFS="PAR_LEFT"> 
      <TextLine ID="P1_TL0000001" HPOS="2362.92" VPOS="160" WIDTH="44.16" HEIGHT="36.04"> 
       <String ID="P1_ST0000001" HPOS="2362.92" VPOS="160" WIDTH="44.16" HEIGHT="36.04" CONTENT="43" /> 
      </TextLine> 
      </TextBlock> 
     </dd> 

我仍然有dd標記,即使它不在我的列表中。爲什麼?謝謝

+0

那是因爲你只是在尋找在第一級的後代。你需要的是遞歸。 –

+0

你能教我如何做遞歸? –

+0

@HristoYankov ['Descendants()'](https://msdn.microsoft.com/en-us/library/bb360635(v = vs.110).aspx)返回所有後代元素,而不僅僅是第一級(不像['元素()'](https://msdn.microsoft.com/en-us/library/bb342765(v = vs.110)的.aspx))。 –

回答

1

的問題是,當你與它的元素的項目是從的XDocument取出並更換項目等都是它的孩子,所以當你嘗試刪除所有被刪除的元素的孩子,在你的情況下,它的<dd>元素與xDocument分離,所以對它沒有任何影響。爲了克服這個問題,你需要存儲的元素要刪除的父母,然後在其子女遞歸遍歷

public static void RemoveRecursive(XElement current, List<string> goodNames) 
    { 
     var parent = current; 
     if (!goodNames.Contains(current.Name.ToString())) 
     { 
      parent = current.Parent; 

      current.ReplaceWith(current.Elements()); 
     } 
     foreach (var element in parent.Elements()) 
     { 
      RemoveRecursive(element, goodNames); 
     } 

    } 

試試這個函數,其中currentdoc.RootgoodNameslstApprove

+0

非常感謝你的工作 –

0

我認爲你的代碼的問題是你錯過了關於替換中「/ document」的正斜槓。下面的代碼工作

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     static void Main(string[] args) 
     { 
      List<string> lstApprove = new List<string>() { 
       "Styles", "alto", "Description", "MeasurementUnit", 
       "sourceImageInformation", 
       "fileName", "OCRProcessing", "preProcessingStep", 
       "processingSoftware", "softwareCreator", "softwareName", 
       "softwareVersion", "ocrProcessingStep", "ParagraphStyle", 
       "Layout", "Page", "PrintSpace", "TextBlock", 
       "TextLine", "String", "SP", "ComposedBlock", "GraphicalElement" 
      }; 


      XDocument doc = XDocument.Load(FILENAME); 

      List<XElement> elements = doc.Descendants().Where(x => lstApprove.Contains(x.Name.LocalName)).ToList(); 

      string xml = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>" + 
         "<document xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"></document>"; 

      XDocument newDoc = XDocument.Parse(xml); 
      XElement document = (XElement)newDoc.FirstNode; 
      document.Add(elements); 
     } 
    } 
}