Fetching and modifying the child elements in an xml Document

岁酱吖の 提交于 2019-12-24 19:03:52

问题


Here is a tricky bit of situation. I have a webservice that returns an XML document. This XML document has a root element that is called <Entities .... > The Entities element has child elements called <Article..>. I need to modify one of the child elements of Article and "PUT" each article element back to the webservice. The reason why I can not post the whole document with Entities is because the webservice does not recognize the Entities as an object and I can not perform an update operation on it.

Below is the structure of the document received:

<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>

Below is the code that I have used to do the trick but I can fetch the Sla element. What I need to do is to get the Sla elements in each article and run a check against its id attribute. If the check comes true, I need to remove that Sla element along with all of its child elements. This is what I have done so far:

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;
            }


            }

I cant get the code to work because when I reach the

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

it does not populate the Slanode and it returns null, when I checked the nodes in debug mode, the list was showing the following error:

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

any help would be greatly appreciated.

Thanks


回答1:


Path is wrong

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

should be

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

I think.




回答2:


I'm going to re-write that with XElement, hopefully that works for you as XElement is what I understand.

First get the Article to remove:

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

To make the loop readable, create a Put function:

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();
    }
}

Then get the rest of the articles and upload them:

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

Edit: To use XPath with XElement you need to use the following using:

using System.Xml.XPath;


来源:https://stackoverflow.com/questions/11706179/fetching-and-modifying-the-child-elements-in-an-xml-document

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!