2013-10-27 2 views
0

내가 입력 XML은선택 XML에서 노드와 새로운 XML

배열을 계속 내 XML을 제거하고 문자열에있는 경우에만 노드를 유지하기 위해 노력하고 만들기

<Employees> 
    <Employee> 
    <EmpId>1</EmpId> 
    <Name>Sam</Name> 
    <Sex>Male</Sex> 
    <Address> 
     <Country>USA</Country> 
     <Zip>95220</Zip> 
    </Address> 
    </Employee> 
    <Employee> 
    <EmpId>2</EmpId> 
    <Name>Lucy</Name> 
    <Sex>Female</Sex> 
    <Address> 
     <Country>USA</Country> 
     <Zip>95220</Zip> 
    </Address> 
    </Employee> 
</Employees> 

내가 필요로 출력

입니다
<Employees> 
    <Employee> 
    <EmpId>1</EmpId> 
    <Sex>Male</Sex> 
    <Address> 
    <Zip>95220</Zip> 
    </Address> 
    </Employee> 
    <Employee> 
    <EmpId>2</EmpId> 
    <Sex>Female</Sex> 
    <Address> 
     <Zip>95220</Zip> 
    </Address> 
    </Employee> 
</Employees> 

내 코드는 다음과 같습니다.

private void button1_Click(object sender, EventArgs e) 
      { 
       XmlDocument xDoc = new XmlDocument(); 

      xDoc.Load(XML_Path); 
      // xDoc.Load(); 
      XmlNodeList xNodes = xDoc.SelectNodes("Employees/Employee"); 
      XmlDocument doc = new XmlDocument(); 
      XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null); 
      doc.AppendChild(docNode); 

      XmlNode employeesNode = doc.CreateElement("Employees"); 
      doc.AppendChild(employeesNode); 
      string s =null; 
      string keep = "EmpId,Sex,Address/Zip"; 
      string[] strArr = keep.Split(','); 
      foreach(XmlNode xN in xNodes) 
      { 
       XmlNode employeeNode = doc.CreateElement("Employee"); 
       employeesNode.AppendChild(employeeNode); 

       foreach (string str in strArr) 
       { 
        XmlNode xNod = xN.SelectSingleNode(str); 
        employeeNode.AppendChild(xNod); 

       } 

      } 
      richTextBox1.Text = doc.ToString(); 

     } 

내부 foreach 루프에 이상한 오류가 발생합니다. 새 노드를 추가하면 아무런 문제가 없음을 알 수 있습니다.

감사

답변

0

코드는 매우 간결 것, XML로 사용하여이 Linq에보십시오.

private void button1_Click(object sender, EventArgs e) 
{ 
    var xDoc = XDocument.Load(XML_Path) 
    string keep = "EmpId,Sex,Address,Zip"; 
    string[] strArr = keep.Split(','); 

    var nodesToDelete = xDoc.Root.Descendants("Employee") 
     .SelectMany(e => e.Descendants() 
          .Where(a => !strArr.Contains(a.Name.ToString()))); 

    foreach (var node in nodesToDelete.ToList()) 
     node.Remove(); 

    richTextBox1.Text = xDoc.ToString(); 
} 
+0

고마워요.이 제네릭을 만들려고 노력하고 있습니다. 그래서 더 많은 노드가있을 것입니다. 이름 주소/국가 등은 제거되어야합니다 .. 문자열 유지는 실제로 winform에서 오는 textBox.Text입니다. 내가 무엇을 유지해야하는지 정의 할 것이다. – user2920743

+0

@ user2920743, 업데이트 된 답변을 확인하십시오. 슬래시 구분 기호없이 유지할 노드를 넣으십시오. –

0

XDocument 사용 방법은 어떻습니까?

벨로우즈 코드는 필요한 출력을 제공합니다.

string xmlString = 
      @"<?xml version=""1.0""?> 
      <Employees> 
       <Employee> 
       <EmpId>1</EmpId> 
       <Name>Sam</Name> 
       <Sex>Male</Sex> 
       <Address> 
        <Country>USA</Country> 
        <Zip>95220</Zip> 
       </Address> 
       </Employee> 
       <Employee> 
       <EmpId>2</EmpId> 
       <Name>Lucy</Name> 
       <Sex>Female</Sex> 
       <Address> 
        <Country>USA</Country> 
        <Zip>95220</Zip> 
       </Address> 
       </Employee> 
      </Employees> 
      "; 

     System.Xml.Linq.XDocument xmlDoc = System.Xml.Linq.XDocument.Parse(xmlString); 

     foreach (var employee in xmlDoc.Descendants("Employee")) 
     { 
      employee.Descendants("Name").First().Remove(); 

      employee.Descendants("Address").First().Descendants("Country").First().Remove(); 
     } 

     MessageBox.Show(xmlDoc.ToString()); 
+0

고맙습니다. 제네릭을 만들려고합니다. 가능한 노드가 많을 것입니다. 이름/주소 등이 있습니다. 제거해야합니다 .. String Keep은 실제로 winform에서 오는 textBox.Text이며 이것은 무엇을 유지해야하는지 정의합니다. 그래서 어떤 태그를 제거해야하는지 잘 모르겠지만 유지해야하는 것은 무엇인지 알 수 있습니다 .. – user2920743

+0

제거를하는 대신 태그를 보관할 수있는 방법이 있습니까? – user2920743

0

이 같은 뭔가 갈 수 : 당신의 keep 배열이 변경 될 수 있으며 다른 시나리오가 요구 될 수 있기

XmlDocument source = new XmlDocument(); 
source.LoadXml(xmldata); 

var keep = new[] {"EmpId", "Sex", "Address/Zip"}; 
foreach (XmlElement employee in source.SelectNodes("/Employees/Employee")) 
foreach (XmlElement child in employee.SelectNodes(".//*")) 
{ 
    if(keep.Any(i => i.StartsWith(child.Name) || i.EndsWith(child.Name))) 
     continue; 

    child.ParentNode.RemoveChild(child); 
} 
Console.WriteLine(source.OuterXml); 

그러나, 당신은 XSLT 변환과 함께 할 것입니다 시도해야합니다.

관련 문제