XPath 与 Yahoo API

发布于 2024-08-02 09:54:52 字数 2665 浏览 3 评论 0原文

我一直在摸索如何使用 C#/XPath/SelectNodes 从 Yahoo API XML 结果中提取节点。

下所述相同的问题

我基本上遇到了与C# XmlDocument SelectNodes 以及SelectNodes not work on stackoverflow feed

我陷入困境的一点on 是准确理解使用什么作为 xmlns,以及在引用 XPath 中的节点时为什么/是否需要使用前缀,因为 XML 节点本身没有前缀。 .Net 3.5 不是该项目的选项。

我的代码尝试(几次迭代之一):

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xml);

        XmlNameTable table = new NameTable();
        XmlNamespaceManager mgr = new XmlNamespaceManager(table);
        mgr.AddNamespace("lcl", "urn:yahoo:lcl");

        XmlNodeList nodes = doc.GetElementsByTagName("//lcl:ResultSet/Result");
        // !nodes.Count is zero.

以及我正在使用的 XML:

<?xml version="1.0"?>
<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="urn:yahoo:lcl" 
xsi:schemaLocation="urn:yahoo:lcl http://local.yahooapis.com/LocalSearchService/V3/LocalSearchResponse.xsd" 
totalResultsAvailable="35" totalResultsReturned="1" firstResultPosition="1">
<ResultSetMapUrl>http://maps.yahoo.com/broadband/?q1=San+Diego%2C+CA&amp;tt=Pizza&amp;tp=1</ResultSetMapUrl>
<Result id="20850086"><Title>Filippi's Pizza Grotto</Title><Address>1747 India St</Address>
<City>San Diego</City><State>CA</State><Phone>(619) 232-5094</Phone><Latitude>32.723421</Latitude>
<Longitude>-117.168194</Longitude><Rating><AverageRating>4</AverageRating>
<TotalRatings>115</TotalRatings><TotalReviews>32</TotalReviews><LastReviewDate>1246565979</LastReviewDate>
<LastReviewIntro>... edited ...</ClickUrl>
<MapUrl>http://maps.yahoo.com/maps_result?q1=1747+India+St+San+Diego+CA&amp;gid1=20850086</MapUrl>
<BusinessUrl>http://www.realcheesepizza.com/</BusinessUrl>
<BusinessClickUrl>http://www.realcheesepizza.com/</BusinessClickUrl><Categories><Category id="96926243">Pizza</Category>
<Category id="96926190">Italian Restaurants</Category>
<Category id="96926233">Continental Restaurants</Category>
<Category id="96926234">Carry Out &amp; Take Out</Category><Category id="96926236">Restaurants</Category>
</Categories></Result></ResultSet>
<!-- ws01.ydn.gq1.yahoo.com uncompressed/chunked Thu Aug 20 17:56:17 PDT 2009 -->

I have been scratching my head trying to figure out how to use C#/XPath/SelectNodes to extract nodes from a Yahoo API XML result.

I essentially have the same problem as stated under

C# XmlDocument SelectNodes
as well as under SelectNodes not working on stackoverflow feed

The point I'm stuck on is understanding exactly what to use as the xmlns, and why/whether I need to use a prefix when referencing the node in XPath as the XML nodes themselves have no prefix. .Net 3.5 is not an option for this project.

My code attempt (one of several iterations):

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xml);

        XmlNameTable table = new NameTable();
        XmlNamespaceManager mgr = new XmlNamespaceManager(table);
        mgr.AddNamespace("lcl", "urn:yahoo:lcl");

        XmlNodeList nodes = doc.GetElementsByTagName("//lcl:ResultSet/Result");
        // !nodes.Count is zero.

and the XML I'm working with:

<?xml version="1.0"?>
<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="urn:yahoo:lcl" 
xsi:schemaLocation="urn:yahoo:lcl http://local.yahooapis.com/LocalSearchService/V3/LocalSearchResponse.xsd" 
totalResultsAvailable="35" totalResultsReturned="1" firstResultPosition="1">
<ResultSetMapUrl>http://maps.yahoo.com/broadband/?q1=San+Diego%2C+CA&tt=Pizza&tp=1</ResultSetMapUrl>
<Result id="20850086"><Title>Filippi's Pizza Grotto</Title><Address>1747 India St</Address>
<City>San Diego</City><State>CA</State><Phone>(619) 232-5094</Phone><Latitude>32.723421</Latitude>
<Longitude>-117.168194</Longitude><Rating><AverageRating>4</AverageRating>
<TotalRatings>115</TotalRatings><TotalReviews>32</TotalReviews><LastReviewDate>1246565979</LastReviewDate>
<LastReviewIntro>... edited ...</ClickUrl>
<MapUrl>http://maps.yahoo.com/maps_result?q1=1747+India+St+San+Diego+CA&gid1=20850086</MapUrl>
<BusinessUrl>http://www.realcheesepizza.com/</BusinessUrl>
<BusinessClickUrl>http://www.realcheesepizza.com/</BusinessClickUrl><Categories><Category id="96926243">Pizza</Category>
<Category id="96926190">Italian Restaurants</Category>
<Category id="96926233">Continental Restaurants</Category>
<Category id="96926234">Carry Out & Take Out</Category><Category id="96926236">Restaurants</Category>
</Categories></Result></ResultSet>
<!-- ws01.ydn.gq1.yahoo.com uncompressed/chunked Thu Aug 20 17:56:17 PDT 2009 -->

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我一直都在从未离去 2024-08-09 09:54:52

我忍不住说这看起来有点像家庭作业。代码中存在一些错误,给人留下了故意犯错的印象。

  • 为什么要向 GetElementsByTagName() 提供 XPath 表达式?
  • 为什么要创建一个与实际 XML 文档无关的新 NameTable
  • 为什么对路径中的第一个元素 (ResultSet) 使用命名空间前缀,而不对第二个元素 (Result) 使用命名空间前缀,即使它们都位于同一命名空间中?

这有效:

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("lcl", "urn:yahoo:lcl");

XmlNodeList nodes = doc.SelectNodes("/lcl:ResultSet/lcl:Result", mgr);

I can't help but say that this looks a bit like homework. There are some mistakes in the code that leave the impression of being deliberately made wrong.

  • Why do you feed an XPath expression to GetElementsByTagName()?
  • Why do you create a new NameTable that has no relation to the actual XML document?
  • Why do you use a namespace prefix for the first element in the path (ResultSet), but not for the second (Result), even though they both are in the same namespace?

This works:

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("lcl", "urn:yahoo:lcl");

XmlNodeList nodes = doc.SelectNodes("/lcl:ResultSet/lcl:Result", mgr);
书信已泛黄 2024-08-09 09:54:52

尝试

XmlNodeList nodes = doc.SelectNodes("//lcl:ResultSet/lcl:Result",mgr);

xml 中的节点没有前缀,但它们确实有 xmlns="..." 指定的命名空间。因此,在执行 XPath 查询时,您需要为要搜索的元素提供名称空间。命名空间管理器和前缀允许您执行此操作。

只需使用一个斜杠,您的查询可能会运行得更快一些。

XmlNodeList nodes = doc.SelectNodes("/lcl:ResultSet/lcl:Result",mgr);

Try

XmlNodeList nodes = doc.SelectNodes("//lcl:ResultSet/lcl:Result",mgr);

The nodes in the xml do not have a prefix but they do have a namespace as specified by xmlns="...". Therefore when doing an XPath query you need to provide a namespace for the elements you are searching for. The namespace manager and the prefix allow you to do this.

Your query would probably work a little quicker using just a single slash.

XmlNodeList nodes = doc.SelectNodes("/lcl:ResultSet/lcl:Result",mgr);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文