3

这是我第一次尝试使用 C# 解析 XML,感觉就像我现在在兜圈子。我正在调用 WCF Web 服务,该服务根据用户输入通过数据库对公司名称进行搜索。它以 XML 文档的形式返回结果,每个条目的格式如下所示。

鉴于这种 XML 结构,我将如何使用 获取 d:AccountIdd:Name节点的值C#

<entry>
    <id></id>
    <title type=\"text\"></title>
    <updated></updated>
    <author><name /></author>
    <link rel=\"edit\" title=\"Account\" href=\"AccountSet\" />
    <category term=\"Microsoft.Crm.Sdk.Data.Services.Account\" scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" />
    <content type=\"application/xml\">
    <m:properties>
        <d:neu_UniqueId></d:neu_UniqueId>
        <d:AccountId m:type=\"Edm.Guid\"></d:AccountId>
        <d:Name></d:Name>
    </m:properties></content>
</entry>

这是我的第一次尝试。node3程序在变量处引发了异常。

        try
        {
            WebRequest myWebRequest = WebRequest.Create(URL);
            myWebRequest.PreAuthenticate = true;
            myWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;

            //myWebRequest.Headers.Add("Access-Control-Allow-Origin", url);

            WebResponse myWebResponse = myWebRequest.GetResponse();
            Stream myFileStreamResult = myWebResponse.GetResponseStream();
            Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
            StreamReader readStream = new StreamReader(myFileStreamResult, encoder);

            results = readStream.ReadToEnd();

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(results);
            XmlNodeList parentNode = xmlDoc.GetElementsByTagName("entry");

            foreach (XmlNode childNode in parentNode)
            {

                string node = childNode.ToString();
                string node2 = childNode.Value;
                string node3 = childNode.Attributes["title"].Value;
                string node7 = childNode.Attributes["m:properties"].Value;
                string node8 = childNode.Attributes["m:properties\\d:AccountId"].Value;
                string node9 = childNode.Attributes["m:properties\\d:Name"].Value;
                string node10 = childNode.Attributes["m:properties\\d:AccountId"].Value;
            }

        }
4

2 回答 2

3

假设 API 可靠地返回 XML 结构,您可以简单地指定节点的路径,"/entry/m:properties"然后调用 get children。之后,您需要遍历这些节点,检查您想要的节点。

当前,您的 foreach 循环正在尝试在<id></id>节点上执行所有导致异常的操作,因为没有“title”属性。

所以给出一些示例代码,你正在寻找这样的东西;

XmlNode props = root.SelectSingleNode("/entry/m:properties");
for (int i = 0; i < props.ChildNodes.Count; i++)
{
    if (propes.ChildNodes[i].Name = "node I want")
    {
         //do something
    }
}

或者,如果您只需要这两个值,则只需使用SelectSingleNode该节点的完整路径。从您的问题来看,听起来没有理由使用迭代。所以你可以简单地做;

   string accountName = root.SelectSingleNode("/entry/m:properties/d:Name").InnerXml;

获取帐户名称。

于 2013-04-24T16:46:38.317 回答
2

使用 Linq2Xml 可能会更容易一些。

var xml = "<entry xmlns:m=\"ns1\" xmlns:n=\"ns2\" xmlns:d=\"ns3\">" +
 "<id></id>" +
 "<title type=\"text\"></title>" +
 "<updated></updated>" +
 "<author><name /></author>" +
 "<link rel=\"edit\" title=\"Account\" href=\"AccountSet\" />" +
 "<category term=\"Microsoft.Crm.Sdk.Data.Services.Account\" scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" />" +
 "<content type=\"application/xml\">" +
 "<m:properties>" +
     "<d:neu_UniqueId></d:neu_UniqueId>" +
     "<d:AccountId m:type=\"Edm.Guid\">Account ID</d:AccountId>" +
     "<d:Name>Account Name</d:Name>" +
 "</m:properties></content>" +
"</entry>";

        const string namespaceM = "ns1";
        const string namespaceD = "ns3";

        using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
        {
            using (var reader = XmlReader.Create(stream))
            {
                var document = XDocument.Load(reader, LoadOptions.None);
                var contentNode = document.Elements().First().Elements().First(e => e.Name.LocalName == "content");
                var propertiesNode = contentNode.Elements().First(d => d.Name.LocalName == "properties" && d.Name.Namespace == namespaceM);
                var accountIdNode = propertiesNode.Elements().First(d => d.Name.LocalName == "AccountId" && d.Name.Namespace == namespaceD);
                var nameNode = propertiesNode.Elements().First(d => d.Name.LocalName == "Name" && d.Name.Namespace == namespaceD);
                var accountIdText = accountIdNode.Value;
                var nameText = nameNode.Value;
            }
        }
于 2013-04-24T17:00:44.420 回答