【问题标题】:XPath with Yahoo API带有 Yahoo API 的 XPath
【发布时间】:2009-08-21 01:04:21
【问题描述】:

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

我基本上遇到了与以下所述相同的问题

C# XmlDocument SelectNodes 以及SelectNodes not working on stackoverflow feed下的@

我坚持的一点是准确地理解将什么用作 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 -->

【问题讨论】:

    标签: xpath .net-2.0


    【解决方案1】:

    我不得不说这看起来有点像家庭作业。代码中有一些错误,给人的印象是故意弄错

    • 为什么要将 XPath 表达式提供给 GetElementsByTagName()
    • 为什么要创建一个与实际 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);
    

    【讨论】:

    • 不是作业,只是第一次使用带有命名空间的 XPath :-) 关键是使用文档中的现有名称表。
    【解决方案2】:

    试试

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

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

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

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

    【讨论】:

    • 那没有成功 :-( 我对实际的命名空间感到困惑。鉴于mgr.AddNamespace("lcl", "urn:yahoo:lcl"); 行,“urn:yahoo:lcl”是否正确?我见过的其他例子有“http://....”格式。
    • 我不是 100% 确定,但我认为命名空间几乎可以是任何东西。没有预定义的格式。按照惯例,人们倾向于使用 URL 样式的命名空间,但这只是一个惯例。我错过了 Tomalak 发现的 NameTable 错误。
    • 感谢您提供有关命名空间的信息并尝试帮助解决此问题。
    猜你喜欢
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2012-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多