2012-07-29 2 views
0

여기 까다로운 상황이 있습니다. XML 문서를 반환하는 웹 서비스가 있습니다. 이 XML 문서에는 <Entities .... >이라는 루트 요소가 있습니다. Entities 요소에는 <Article..>이라는 자식 요소가 있습니다. Article의 하위 요소 중 하나를 수정하고 각 기사 요소를 웹 서비스로 다시 가져와야합니다. 엔티티로 전체 문서를 게시 할 수없는 이유는 웹 서비스가 엔티티를 객체로 인식하지 못하고 객체로 객체를 업데이트 할 수 없기 때문입니다.xml 문서의 하위 요소 가져 오기 및 수정

다음은 문서의 구조가 수신 : 아래

<Entities> 
    <Article id="1"> 
    <Permissions> 
     <Sla id="1"> 
     <name> first sla </name> 
     </Sla> 
     </Permissions> 
    </Article> 
    <Article id="2"> 
    <Permissions> 
     <Sla id="2"> 
     <name> second sla </name> 
     </Sla> 
     </Permissions> 
    </Article> 
</Entities> 

내가 트릭을 할하는 데 사용한 코드입니다하지만 난 SLA에 요소를 가져올 수 있습니다. 내가해야 할 일은 각 기사에서 Sla 요소를 가져 와서 id 속성에 대한 검사를 실행하는 것입니다. 검사 결과가 나오면 Sla 요소와 그 자식 요소를 모두 제거해야합니다. 이것은 내가 지금까지 한 일이다 : 나는 그것이 Slanode을 채우지 않는

Slanode = doc.SelectSingleNode("Permissions/Sla[@id='" + sla.ToString() + "']");

에 도달하면 때문에

int pageNumber = 1; 
bool entities = true; 
while (entities) 
{ 
url = "www.myurl.com"; 
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); 
req.Method = "Get"; 
HttpWebResponse rep = (HttpWebResponse)req.GetResponse(); 
doc.Load(rep.GetResponseStream()); 
rep.Close(); 
if (doc != null) 
{ 
       XmlNodeList nodes = doc.SelectNodes("/Entities/Article"); 
       foreach (XmlNode node in nodes) 
       { 
        XmlNode Slanode = null; 
        try 
        { 
         Slanode = doc.SelectSingleNode("Permissions/Sla[@id='" + sla.ToString() + "']"); 
         Slanode.ParentNode.RemoveChild(node); 
         string finalXML = doc.OuterXml; 
         HttpWebRequest reqToUpdate = (HttpWebRequest)WebRequest.Create(url); 
         reqToUpdate.ContentType = "text/xml; encoding=UTF-8"; 
         reqToUpdate.Method = "PUT"; 
         byte[] bytes = new UTF8Encoding().GetBytes(finalXML); 
         reqToUpdate.ContentLength = bytes.Length; 
         Stream data = reqToUpdate.GetRequestStream(); 
         data.Write(bytes, 0, bytes.Length); 
         data.Close(); 
        } 
        catch (Exception error) 
        { 
         MessageBox.Show(error.Message); 
        } 


       } 


       pageNumber++; 
       } 
       else 
        entities = false; 
      } 


      } 

내가 코드가 작동하도록 어차피 그것은 null을 반환 때

Only one top level element is allowed in an XML document. Error processing resource

도움이 될 것이다 : 디버그 모드에서 노드를 체크리스트는 다음과 같은 오류를 보여주는데 대단히 감사합니다.

감사

답변

1

경로

Slanode = doc.SelectSingleNode("Permissions/Sla[@id='" + sla.ToString() + "']"); 

내가 생각

Slanode = node.SelectSingleNode("Permissions/Sla[@id='" + sla.ToString() + "']"); 

해야 잘못된 것입니다.

1

XElement로 다시 작성하겠습니다. XElement는 내가 이해하는대로 잘 작동합니다. ,

XElement root = XElement.Load(stream); 
XElement articleToRemove = root.XPathSelectElement("//Article[Permissions/Sla/@id='"+sla.ToString()+"']"); 
if(null != articleToRemove) 
    articleToRemove.Remove(); 

루프가 쉽게 읽을 수 있도록하기 위해 풋 기능을 만들 :

private void Put(XElement article) 
{ 
    Stream data = null; 
    try 
    { 
     string finalXML = article.ToString(SaveOptions.DisableFormatting); 
     HttpWebRequest reqToUpdate = (HttpWebRequest)WebRequest.Create(url); 
     reqToUpdate.ContentType = "text/xml; encoding=UTF-8"; 
     reqToUpdate.Method = "PUT"; 
     byte[] bytes = new UTF8Encoding().GetBytes(finalXML); 
     reqToUpdate.ContentLength = bytes.Length; 
     data = reqToUpdate.GetRequestStream(); 
     data.Write(bytes, 0, bytes.Length); 
    } 
    catch (Exception error) 
    { 
     MessageBox.Show(error.Message); 
    } 
    finally 
    { 
     if (null != data) 
      data.Close(); 
    } 
} 

그런 다음 기사의 나머지를 얻을 수 및 업로드 :

을 제거하기 위해 문서를 얻을

우선

root.Descendants("Article").ToList().ForEach(a => Put(a)); 

편집 : XElement와 함께 XPath를 사용하려면 다음을 사용하여 다음을 사용해야합니다.

using System.Xml.XPath; 
관련 문제