按节点值查找Xml节点
本文关键字:节点 Xml 查找 | 更新日期: 2023-09-27 18:28:46
我创建了一个项目来阅读亚马逊产品广告API,使用以下代码检索XML文档:
WebRequest request = HttpWebRequest.Create(signedurl);
WebResponse responseStream = request.GetResponse();
XmlDocument doc = new XmlDocument();
doc.Load(responseStream.GetResponseStream());
而且,通过进一步的研究,我已经能够使用以下内容访问元素值;
XmlNode Item_IdNode = doc.GetElementsByTagName("ASIN").Item(0);
XmlNode PriceNode = doc.GetElementsByTagName("FormattedPrice").Item(3);
string F_Price = PriceNode.InnerText;
string xml_ItemId = Item_IdNode.InnerText;
此代码适用于访问产品ASIN和单个记录的价格,但我希望每个请求最多检索10条记录。
到目前为止,我知道我可以增加"项目(0)"来浏览其他项目ASIN,但"FormattedPrice"元素在每个产品中重复多次,对于其他产品记录,可能不一定出现在第6,9,12点。
对于检索到的每10条记录,我已经知道(使用)api调用中的ASIN(唯一产品参考)来选择特定的记录。
我想将代码推进到的地方是"搜索"物品ASIN"12345"的XML响应,然后深入到特定节点"OfferSummary/LowestNewPrice/FormattedPrice",将物品价格检索到变量中,依此类推,以查找所有其他ASIN的物品价格。
以下是前两个XML项记录的摘录(如果有帮助的话)。
<Items>
<Request>
<IsValid>True</IsValid>
<ItemLookupRequest>
<Item><ASIN>12345</ASIN>
<OfferSummary>
<LowestNewPrice>
<Amount>1098</Amount>
<CurrencyCode>GBP</CurrencyCode>
<FormattedPrice>£10.98</FormattedPrice>
</LowestNewPrice>
</OfferSummary>
.
.
.
.
<Items>
<Request>
<IsValid>True</IsValid>
<ItemLookupRequest>
<Item><ASIN>23456</ASIN>
<OfferSummary>
<LowestNewPrice>
<Amount>1098</Amount>
<CurrencyCode>GBP</CurrencyCode>
<FormattedPrice>£10.98</FormattedPrice>
</LowestNewPrice>
</OfferSummary>
.
.
.
.
我有一些asp.net的经验,但以前没有使用过XML"阅读器",如果能为每个ASIN及其相应的"FormattedPrice"在XML文件中"搜索"正确的方向,我将不胜感激。
希望这是足够的信息,如果需要任何进一步的信息,请告诉我。
非常感谢,James
编辑更新:2016年1月11日
非常感谢大家的回复,我一直在努力将您的回复纳入我的代码中的一个工作样本中(上周,我试图自己弄清楚)。尽管经过许多天的尝试,我仍然没有得到最终的工作解决方案。
我已将我的"查询"调整如下:
var res = XElement.Load(Server.MapPath("/App_Data/AWSS.xml"))
.Descendants("ASIN").FirstOrDefault(elem => elem.Value == "B001MS70F2")
.Parent.Descendants("FormattedPrice").Select(elem => elem.Value)
.FirstOrDefault();
Response.Write(res);
这在一定程度上是可行的,但在我最初的帖子中,我只发布了完整XML数据的摘录。上面的代码适用于我提供的示例XML,但不适用于包括我认为是"根"的完整数据。如果我删除了"ItemLookupResponse"节点(并请求死者),代码可以工作,但不适用于以下完整的XML数据;
<ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
<OperationRequest>
<HTTPHeaders>
<Header Name="UserAgent" Value="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"/>
</HTTPHeaders>
<RequestId>#############</RequestId>
<Arguments>
<Argument Name="AWSAccessKeyId" Value="#############"/>
<Argument Name="AssociateTag" Value="#############"/>
<Argument Name="IdType" Value="ASIN"/>
<Argument Name="ItemId" Value="B001MS70F2,B007W1RSZA"/>
<Argument Name="Operation" Value="ItemLookup"/>
<Argument Name="ResponseGroup" Value="Offers"/>
<Argument Name="Service" Value="AWSECommerceService"/>
<Argument Name="Timestamp" Value="2016-01-06T23:01:02Z"/>
<Argument Name="Signature" Value="#############"/>
</Arguments>
<RequestProcessingTime>0.0209750000000000</RequestProcessingTime>
</OperationRequest>
<Items>
<Request>
<IsValid>True</IsValid>
<ItemLookupRequest>
<IdType>ASIN</IdType>
<ItemId>B001MS70F2</ItemId>
<ItemId>B007W1RSZA</ItemId>
<ResponseGroup>Offers</ResponseGroup>
<VariationPage>All</VariationPage>
</ItemLookupRequest>
</Request>
<Item>
<ASIN>B001MS70F2</ASIN>
<ParentASIN>B019IGAHUY</ParentASIN>
<OfferSummary>
<LowestNewPrice>
<Amount>1049</Amount>
<CurrencyCode>GBP</CurrencyCode>
<FormattedPrice>£10.49</FormattedPrice>
</LowestNewPrice>
<TotalNew>32</TotalNew>
<TotalUsed>0</TotalUsed>
<TotalCollectible>0</TotalCollectible>
<TotalRefurbished>0</TotalRefurbished>
</OfferSummary>
<Offers>
<TotalOffers>1</TotalOffers>
<TotalOfferPages>1</TotalOfferPages>
<MoreOffersUrl>
http://www.amazon.co.uk/gp/offer-listing/B001MS70F2%3FSubscriptionId%3DAKIAI4V5X2Q7F3BOU7MA%26tag%3Dbusin02-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB001MS70F2
</MoreOffersUrl>
<Offer>
<OfferAttributes>
<Condition>New</Condition>
</OfferAttributes>
<OfferListing>
<OfferListingId>
VbyiDUr1A7VXNun65VvEF8WmWG3ZOzirk%2BGjIdOOGBB38lLlcRYaEKyl4pS6hdrqhZuOLqfW4uTVLtqsCUfanWyEaltghotq
</OfferListingId>
<Price>
<Amount>1049</Amount>
<CurrencyCode>GBP</CurrencyCode>
<FormattedPrice>£10.49</FormattedPrice>
</Price>
<AmountSaved>
<Amount>284</Amount>
<CurrencyCode>GBP</CurrencyCode>
<FormattedPrice>£2.84</FormattedPrice>
</AmountSaved>
<PercentageSaved>21</PercentageSaved>
<Availability>Usually dispatched within 24 hours</Availability>
<AvailabilityAttributes>
<AvailabilityType>now</AvailabilityType>
<MinimumHours>0</MinimumHours>
<MaximumHours>0</MaximumHours>
</AvailabilityAttributes>
<IsEligibleForSuperSaverShipping>1</IsEligibleForSuperSaverShipping>
<IsEligibleForPrime>1</IsEligibleForPrime>
</OfferListing>
</Offer>
</Offers>
</Item>
<Item>
<ASIN>B007W1RSZA</ASIN>
<OfferSummary>
<LowestNewPrice>
<Amount>1630</Amount>
<CurrencyCode>GBP</CurrencyCode>
<FormattedPrice>£16.30</FormattedPrice>
</LowestNewPrice>
<TotalNew>7</TotalNew>
<TotalUsed>0</TotalUsed>
<TotalCollectible>0</TotalCollectible>
<TotalRefurbished>0</TotalRefurbished>
</OfferSummary>
<Offers>
<TotalOffers>1</TotalOffers>
<TotalOfferPages>1</TotalOfferPages>
<MoreOffersUrl>
http://www.amazon.co.uk/gp/offer-listing/B007W1RSZA%3FSubscriptionId%3DAKIAI4V5X2Q7F3BOU7MA%26tag%3Dbusin02-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB007W1RSZA
</MoreOffersUrl>
<Offer>
<OfferAttributes>
<Condition>New</Condition>
</OfferAttributes>
<OfferListing>
<OfferListingId>
VbyiDUr1A7VXNun65VvEF74FLb5xO3BqKAr7e2DBjtDJNt3ZXQTDuPuGzaLdifzl2xEs1x4swNRE3U6yP3JfXvjWXxBDUM1vGxR8eaR1suappuRh5ZARKbjoGHx3NvEpVdrLfxvwmIzXoFSSq50uWg%3D%3D
</OfferListingId>
<Price>
<Amount>1630</Amount>
<CurrencyCode>GBP</CurrencyCode>
<FormattedPrice>£16.30</FormattedPrice>
</Price>
<Availability>Usually dispatched within 1-2 business days</Availability>
<AvailabilityAttributes>
<AvailabilityType>now</AvailabilityType>
<MinimumHours>24</MinimumHours>
<MaximumHours>48</MaximumHours>
</AvailabilityAttributes>
<IsEligibleForSuperSaverShipping>0</IsEligibleForSuperSaverShipping>
<IsEligibleForPrime>0</IsEligibleForPrime>
</OfferListing>
</Offer>
</Offers>
</Item>
</Items>
</ItemLookupResponse>
我尝试了许多代码排列,这让我得出结论,删除"ItemLookupResponse"节点会导致错误"multiple root elements"。但是删除"ItemLookupResponse"answers"OperationRequest"会给我提供工作代码。
在完整的XML响应上使用我调整后的"query"(如上)会出现错误"Object reference not set to a instance of a Object"
如果有人能为我指明正确的方向,让我在完整的XML上运行经过调整的"查询",并克服"对象引用未设置为对象实例"的错误,我将不胜感激。
非常感谢,James
您可以使用LINQ to XML-这将返回给定ASIN值的格式化价格:
var res = XElement.Parse("data.xml")
.Descendants("ASIN").FirstOrDefault(elem => elem.Value == "12345")
.Parent.Descendants("FormattedPrice").Select(elem => elem.Value)
.FirstOrDefault();
如果您想在文档中获取所有ASIN:
var asins = XElement.Parse("data.xml")
.Descendants("ASIN")
.Select(elem => elem.Value)
.ToList();
编辑-由于省略了名称空间而出现的问题-请检查msdn上的LINQ to XML名称空间。
XNamespace ns = "http://webservices.amazon.com/AWSECommerceService/2011-08-01";
var res = XElement.Load("data.xml")
.Descendants(ns+ "ASIN").FirstOrDefault(elem => elem.Value == "B001MS70F2")
.Parent.Descendants(ns + "FormattedPrice").Select(elem => elem.Value)
.FirstOrDefault();
Console.WriteLine(res); // prints L10.49
还可以看看这个关于SO:XElement命名空间的问题(如何?)
在msdn上:https://msdn.microsoft.com/en-us/library/system.xml.linq.xnamespace(v=vs.110).aspx
static void Main(string[] args)
{
string xml = @"<ParentNode>
<Items>
<Request>
<IsValid>True</IsValid>
<ItemLookupRequest>
<Item>
<ASIN>B001MS70F1</ASIN>
<OfferSummary>
<LowestNewPrice>
<Amount>1098</Amount>
<CurrencyCode>GBP</CurrencyCode>
<FormattedPrice>£15.98</FormattedPrice>
</LowestNewPrice>
</OfferSummary>
</Item>
</ItemLookupRequest>
</Request>
</Items>
<Items>
<Request>
<IsValid>True</IsValid>
<ItemLookupRequest>
<Item>
<ASIN>B001MS70212</ASIN>
<OfferSummary>
<LowestNewPrice>
<Amount>1098</Amount>
<CurrencyCode>GBP</CurrencyCode>
<FormattedPrice>£10.98</FormattedPrice>
</LowestNewPrice>
</OfferSummary>
</Item>
</ItemLookupRequest>
</Request>
</Items>
</ParentNode>";
XDocument doc = XDocument.Parse(xml);
List<XElement> elements = doc.Descendants("Item").ToList();
foreach(XElement elem in elements)
{
string asin = elem.Element("ASIN").Value;
string formatedPrice = elem.Element("OfferSummary").Element("LowestNewPrice").Element("FormattedPrice").Value;
//you can use this for formated price too
string formatedPrice2 = elem.Descendants("FormattedPrice").FirstOrDefault().Value;
Console.WriteLine("ASIN: " + asin + " and Price:" + formatedPrice);
}
Console.ReadKey();
}
下面是一个示例程序,下次至少发布有效的xml。您需要添加using System.Xml.Linq;
参考
我会使用LINQ to XML解析数据,然后创建这样的查询:
var prices = from item in doc.Descendants("Item")
from summary in item.Elements("OfferSummary")
from lowestNewPrice in summary.Elements("LowestNewPrice")
select new
{
ASIN = (string) item.Element("ASIN"),
FormattedPrice = (string) lowestNewPrice.Element("FormattedPrice")
};
然后,您可以将其转换为字典,或者简单地查询您的ASIN:
var price = prices.Where(x => x.ASIN == "12345")
.Select(x => x.FormattedPrice)
.Single();
请参阅此小提琴以获取工作示例。