我该如何在C#中使用XML前缀?

3

编辑:我现在已经发布了我的应用程序:http://pastebin.com/PYAxaTHU

我试图制作一个基于控制台的应用程序,返回我的温度。

using System;
using System.Xml;


namespace GetTemp
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(downloadWebPage(
             "http://www.andrewmock.com/uploads/example.xml"
            ));

            XmlNamespaceManager man = new XmlNamespaceManager(doc.NameTable);
            man.AddNamespace("aws", "www.aws.com/aws");

            XmlNode weather = doc.SelectSingleNode("aws:weather", man);
            Console.WriteLine(weather.InnerText);
            Console.ReadKey(false);
        }


    }
}

这是一个示例XML文件:

以下是示例代码:

<aws:weather xmlns:aws="http://www.aws.com/aws">
   <aws:api version="2.0"/>
   <aws:WebURL>http://weather.weatherbug.com/WA/Kenmore-weather.html?ZCode=Z5546&Units=0&stat=BOTHL</aws:WebURL>
   <aws:InputLocationURL>http://weather.weatherbug.com/WA/Kenmore-weather.html?ZCode=Z5546&Units=0</aws:InputLocationURL>
   <aws:station requestedID="BOTHL" id="BOTHL" name="Moorlands ES" city="Kenmore" state=" WA" zipcode="98028" country="USA" latitude="47.7383346557617" longitude="-122.230278015137"/>
   <aws:current-condition icon="http://deskwx.weatherbug.com/images/Forecast/icons/cond024.gif">Mostly Cloudy</aws:current-condition>
   <aws:temp units="&deg;F">40.2</aws:temp>
   <aws:rain-today units=""">0</aws:rain-today>
   <aws:wind-speed units="mph">0</aws:wind-speed>
   <aws:wind-direction>WNW</aws:wind-direction>
   <aws:gust-speed units="mph">5</aws:gust-speed>
   <aws:gust-direction>NW</aws:gust-direction>
</aws:weather>

我只是不确定如何正确使用 XML 前缀。这里有什么问题吗?


2
简短建议:使用XDocument,而不是XmlDocument。 - H H
2
在命名空间字符串中包括"http://"。 - H H
http:// 在命名空间字符串中没有价值。按设计,命名空间是不透明的字符串(严格的URI);最重要的特征是唯一性。通常方便的做法是基于DNS名称构建命名空间,这样至少您知道任何冲突都不是您的问题!编辑:抱歉Henk-现在我明白了。你是正确的-命名空间URI不匹配是问题所在,正如mark_s在他的答案中指出的那样。所以-是的-如果它是您正在尝试引用的命名空间URI的一部分,http://就有价值了 :-) - Dominic Cronin
1
@DominicCronin:你注意到示例中的ns了吗? - H H
1
请注意,在您的代码中选择的前缀与XML文档本身使用的前缀之间没有任何关系。同样有效的做法是使用 man.AddNamespace("foo", "...") 然后使用 doc.SelectSingleNode("foo:weather")。 - dthorpe
显示剩余2条评论
1个回答

12

好的,根据这个示例中的XML:

<aws:weather xmlns:aws="http://www.aws.com/aws">
   <aws:api version="2.0"/>
   <aws:WebURL>http://weather.weatherbug.com/WA/Kenmore-weather.html?ZCode=Z5546&Units=0&stat=BOTHL</aws:WebURL>
   <aws:InputLocationURL>http://weather.weatherbug.com/WA/Kenmore-weather.html?ZCode=Z5546&Units=0</aws:InputLocationURL>
   <aws:station requestedID="BOTHL" id="BOTHL" name="Moorlands ES" city="Kenmore" state=" WA" zipcode="98028" country="USA" latitude="47.7383346557617" longitude="-122.230278015137"/>
   <aws:current-condition icon="http://deskwx.weatherbug.com/images/Forecast/icons/cond024.gif">Mostly Cloudy</aws:current-condition>
   <aws:temp units="&deg;F">40.2</aws:temp>
   <aws:rain-today units=""">0</aws:rain-today>
   <aws:wind-speed units="mph">0</aws:wind-speed>
   <aws:wind-direction>WNW</aws:wind-direction>
   <aws:gust-speed units="mph">5</aws:gust-speed>
   <aws:gust-direction>NW</aws:gust-direction>
</aws:weather>

你想读取哪个值?

你的代码有问题是因为 XML 命名空间不正确:

你的代码如下:

XmlNamespaceManager man = new XmlNamespaceManager(doc.NameTable);
man.AddNamespace("aws", "www.aws.com/aws");

但 XML 命名空间为:http://www.aws.com/aws

因此你应该这样写:

 XmlNamespaceManager man = new XmlNamespaceManager(doc.NameTable);
 man.AddNamespace("aws", "http://www.aws.com/aws");

因此,要读取例如温度,请使用以下内容:

XmlDocument doc = new XmlDocument();
doc.LoadXml(downloadWebPage("http://www.andrewmock.com/uploads/9/1/0/7/9107466/example.xml"));

XmlNamespaceManager man = new XmlNamespaceManager(doc.NameTable);
man.AddNamespace("aws", "http://www.aws.com/aws");

XmlNode temps = doc.SelectSingleNode("/aws:weather/aws:temp", man);

string tempValue = temps.InnerText;

"40.2"的值赋给tempValue

正如Henk Holtermann在评论中建议的那样 - 使用Linq-to-XML可以更容易地读取此内容:

XDocument doc = XDocument.Load("http://www.andrewmock.com/uploads/9/1/0/7/9107466/example.xml");

XNamespace aws = "http://www.aws.com/aws";

var weatherNode = doc.Document.Descendants(aws + "weather");
var tempNode = weatherNode.Descendants(aws + "temp").FirstOrDefault();

string tempValue = tempNode.Value;
当然,这还没有包括任何错误处理(比如检查weatherNode是否为NULL等),但它可以让你有一个概念。

谢谢!我已经完成了我的应用程序。 - Andrew Mock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接