2014-11-30 2 views
1

Я новичок в XPath. Мне нужна помощь с XPath, необходимая для извлечения названия и авторов книги в конце этого XML. Я пробовал следующий код C# без успеха. Мне просто нужно перечислить название и авторы книги. Похоже, пространство имен xmlns влияет на мои XPaths. Мой код работает, если вручную удалить xmlns. Таким образом, либо я изменяю XPath для учета этого пространства имен, либо выясню способ удаления этого атрибута из XML. Пожалуйста, порекомендуйте.Что такое XPath для этого XML с пространством имен

Здесь C# код:

XmlNodeList nodes = XML.DocumentElement.SelectNodes("//Title"); 
foreach (XmlNode node in nodes) 
{ 
Console.WriteLn(node.Name + " = " + node.InnerText); } 
} 

Вот это XML:

<?xml version="1.0"?> 
<ItemSearchResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01"> 
    <OperationRequest> 
    <RequestId>xxxxx</RequestId> 
    <Arguments> 
     <Argument Name="Condition" Value="All"></Argument> 
     <Argument Name="ResponseGroup" Value="Small,Images"></Argument> 
     <Argument Name="SearchIndex" Value="Books"></Argument> 
    </Arguments> 
    <RequestProcessingTime>0.0735170000000000</RequestProcessingTime> 
    </OperationRequest> 
    <Items> 
    <Request> 
     <IsValid>True</IsValid> 
     <ItemSearchRequest> 
     <Condition>All</Condition> 
     <Keywords>Perl</Keywords> 
     <ResponseGroup>Small</ResponseGroup> 
     <ResponseGroup>Images</ResponseGroup> 
     <SearchIndex>Books</SearchIndex> 
     </ItemSearchRequest> 
    </Request> 
    <TotalResults>3761</TotalResults> 
    <TotalPages>377</TotalPages> 
    <MoreSearchResultsUrl>http://www.amazon.com/gp/redirect.html?camp=2025&amp;creative=386001&amp;location=http%3A%2F%2Fwww.amazon.com%2Fgp%2Fsearch%3Fkeywords%3DPerl%26url%3Dsearch-alias%253Dstripbooks&amp;linkCode=xm2&amp;tag=geo01d-20&amp;SubscriptionId=AKIAJJBQEKP2X72RQ6XA</MoreSearchResultsUrl> 
    <Item> 
     <ASIN>1449303587</ASIN> 
     <DetailPageURL>http://www.amazon.com/Learning-Perl-Randal-L-Schwartz/dp/1449303587%3FSubscriptionId%3DAKIAJJBQEKP2X72RQ6XA%26tag%3Dgeo01d-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1449303587</DetailPageURL> 
     <ItemLinks> 
     <ItemLink> 
      <Description>Technical Details</Description> 
      <URL>http://www.amazon.com/Learning-Perl-Randal-L-Schwartz/dp/tech-data/1449303587%3FSubscriptionId%3DAKIAJJBQEKP2X72RQ6XA%26tag%3Dgeo01d-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D1449303587</URL> 
     </ItemLink> 
     <ItemLink> 
      <Description>All Offers</Description> 
      <URL>http://www.amazon.com/gp/offer-listing/1449303587%3FSubscriptionId%3DAKIAJJBQEKP2X72RQ6XA%26tag%3Dgeo01d-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D1449303587</URL> 
     </ItemLink> 
     </ItemLinks> 
     <SmallImage> 
     <URL>http://ecx.images-amazon.com/images/I/51kTNE8aIXL._SL75_.jpg</URL> 
     <Height Units="pixels">75</Height> 
     <Width Units="pixels">58</Width> 
     </SmallImage> 
     <MediumImage> 
     <URL>http://ecx.images-amazon.com/images/I/51kTNE8aIXL._SL160_.jpg</URL> 
     <Height Units="pixels">160</Height> 
     <Width Units="pixels">123</Width> 
     </MediumImage> 
     <LargeImage> 
     <URL>http://ecx.images-amazon.com/images/I/51kTNE8aIXL.jpg</URL> 
     <Height Units="pixels">500</Height> 
     <Width Units="pixels">385</Width> 
     </LargeImage> 
     <ImageSets> 
     <ImageSet Category="primary"> 
      <SwatchImage> 
      <URL>http://ecx.images-amazon.com/images/I/51kTNE8aIXL._SL30_.jpg</URL> 
      <Height Units="pixels">30</Height> 
      <Width Units="pixels">23</Width> 
      </SwatchImage> 
      <SmallImage> 
      <URL>http://ecx.images-amazon.com/images/I/51kTNE8aIXL._SL75_.jpg</URL> 
      <Height Units="pixels">75</Height> 
      <Width Units="pixels">58</Width> 
      </SmallImage> 
     </ImageSet> 
     </ImageSets> 
     <ItemAttributes> 
     <Author>Randal L. Schwartz</Author> 
     <Author>brian d foy</Author> 
     <Author>Tom Phoenix</Author> 
     <Manufacturer>O'Reilly Media</Manufacturer> 
     <ProductGroup>Book</ProductGroup> 
     <Title>Learning Perl</Title> 
     </ItemAttributes> 
    </Item> 
    </Items> 
</ItemSearchResponse> 

ответ

0

XPath должен быть «// p: Title», и вам нужно сообщить процессору XPath, что префикс пространства имен «p» обозначает пространство имен «http://webservices.amazon.com/AWSECommerceService/2011-08-01». То, как вы устанавливаете привязки пространства имен, зависит от API вашего выбранного процессора XPath. Для C# вы можете найти объяснение того, как сделать это здесь (или во многих, многих других ответах предыдущего StackOverflow):

Xml-SelectNodes with default-namespace via XmlNamespaceManager not working as expected

+0

Большое спасибо, Майкл. Не только пространство имен делает вещи чрезмерно сложными, ссылка на пространство имен не существует. Затем я выяснил способ удаления пространства имен, чтобы упростить мой синтаксический анализ, который подходит для моего приложения. –

+0

Я, конечно, не защищал бы способ XPath 1.0, и ничего не связанное с пространствами имен. Это просто то, с чем мы должны жить. –

1

Вы можете сделать это с помощью Linq к XML:

XDocument xmlDoc = XDocument.Parse(xmlString); 
var q = from el in xmlDoc.Descendants() 
        .Where(x => x.Name.LocalName == "Title" || x.Name.LocalName == "Author") 
        select el; 

foreach (var xElement in q) 
{ 
    Debug.WriteLine(xElement.Name.LocalName + " : " + xElement.Value); 
} 

Выход:

Author : Randal L. Schwartz 
Author : brian d foy 
Author : Tom Phoenix 
Title : Learning Perl 
+0

Он не просил решения LinqToXML, он попросил решение XPath. –

+0

@MichaelKay Все знают о «точной» природе вопроса. Предложение альтернативных решений не так уж плохо, поскольку это может заставить плакат переоценить и переосмыслить проблемное пространство и решение. Высокомерие не является предпочтительной чертой характера STO. – Ottak

+0

Спасибо Оттак и Майкл Кей. Я ценю оба ваших ответа. Будут ли обе ваши решения работать, если узел повторяет печать заголовков и авторов за ? Я опубликовал третье решение, которое, как я понял, рассмотрел мой первоначальный вопрос и масштаб до нескольких . –

0

я, наконец, понял, ответ на мой вопрос. Я просто удалил пространство имен, которое слишком усложняло мой XPath. Ниже приведен код C#. PrintKeyValue просто печатает Key = Value.

  XML = new XmlDocument(); 

      using (XmlTextReader reader = new XmlTextReader("C:\\Path\\File.xml")) 
      { 
       reader.Namespaces = false; 
       XML.Load(reader); 
      } 

      XmlNodeList items = XML.DocumentElement.SelectNodes("//Item"); 
      foreach (XmlNode item in items) 
      { 
       PrintKeyValue("ISBN10", item["ASIN"].InnerText); 

       XmlNode attrib = item.SelectSingleNode(".//ItemAttributes"); 
       PrintKeyValue("Title", attrib["Title"].InnerText); 

       XmlNodeList authors = attrib.SelectNodes(".//Author"); 
       StringBuilder sb = new StringBuilder(); 
       int count = 0; 
       foreach (XmlNode author in authors) 
       { 
        count++; 
        if (count > 1) { sb.Append(", "); } 
        sb.Append(author.InnerText); 
       } 
       PrintKeyValue("Authors", sb.ToString()); 
      } 
Смежные вопросы