1

可能重复:
亚马逊市场 XML 解析

我是在 C# 中解析 XML 的新手,我有一些来自亚马逊 MWS 库的数据,如下所示。我需要解析出各种 ItemAttributes,例如 ItemDimensions。我习惯于 JSON 响应,所以我不确定如何将它应用于 XML。有人可以为我指明正确的方向吗?我用 C# 搜索了 XML Parsing,但没有找到有价值的结果来帮助我完成任务。

<GetMatchingProductResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<GetMatchingProductResult ASIN="1430225491" status="Success">
  <Product>
    <Identifiers>
      <MarketplaceASIN>
        <MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
        <ASIN>1430225491</ASIN>
      </MarketplaceASIN>
    </Identifiers>
    <AttributeSets>
      <ns2:ItemAttributes xml:lang="en-US">
        <ns2:Author>Troelsen, Andrew</ns2:Author>
        <ns2:Binding>Paperback</ns2:Binding>
        <ns2:Brand>Apress</ns2:Brand>
        <ns2:Edition>5</ns2:Edition>
        <ns2:ItemDimensions>
          <ns2:Height Units="inches">9.21</ns2:Height>
          <ns2:Length Units="inches">7.48</ns2:Length>
          <ns2:Width Units="inches">2.52</ns2:Width>
          <ns2:Weight Units="pounds">5.80</ns2:Weight>
        </ns2:ItemDimensions>
        <ns2:IsAutographed>false</ns2:IsAutographed>
        <ns2:IsEligibleForTradeIn>true</ns2:IsEligibleForTradeIn>
        <ns2:IsMemorabilia>false</ns2:IsMemorabilia>
        <ns2:Label>Apress</ns2:Label>
        <ns2:Languages>
          <ns2:Language>
            <ns2:Name>english</ns2:Name>
            <ns2:Type>Unknown</ns2:Type>
          </ns2:Language>
          <ns2:Language>
            <ns2:Name>english</ns2:Name>
            <ns2:Type>Original Language</ns2:Type>
          </ns2:Language>
          <ns2:Language>
            <ns2:Name>english</ns2:Name>
            <ns2:Type>Published</ns2:Type>
          </ns2:Language>
        </ns2:Languages>
        <ns2:ListPrice>
          <ns2:Amount>59.99</ns2:Amount>
          <ns2:CurrencyCode>USD</ns2:CurrencyCode>
        </ns2:ListPrice>
        <ns2:Manufacturer>Apress</ns2:Manufacturer>
        <ns2:NumberOfItems>1</ns2:NumberOfItems>
        <ns2:NumberOfPages>1752</ns2:NumberOfPages>
        <ns2:PackageDimensions>
          <ns2:Height Units="inches">2.60</ns2:Height>
          <ns2:Length Units="inches">9.20</ns2:Length>
          <ns2:Width Units="inches">7.50</ns2:Width>
          <ns2:Weight Units="pounds">5.80</ns2:Weight>
        </ns2:PackageDimensions>
        <ns2:PartNumber>9781430225492</ns2:PartNumber>
        <ns2:ProductGroup>Book</ns2:ProductGroup>
        <ns2:ProductTypeName>ABIS_BOOK</ns2:ProductTypeName>
        <ns2:PublicationDate>2010-05-14</ns2:PublicationDate>
        <ns2:Publisher>Apress</ns2:Publisher>
        <ns2:SmallImage>
          <ns2:URL>http://ecx.images-amazon.com/images/I/51h9Sju5NKL._SL75_.jpg</ns2:URL>
          <ns2:Height Units="pixels">75</ns2:Height>
          <ns2:Width Units="pixels">61</ns2:Width>
        </ns2:SmallImage>
        <ns2:Studio>Apress</ns2:Studio>
        <ns2:Title>Pro C# 2010 and the .NET 4 Platform</ns2:Title>
      </ns2:ItemAttributes>
    </AttributeSets>
    <Relationships/>
    <SalesRankings>
      <SalesRank>
        <ProductCategoryId>book_display_on_website</ProductCategoryId>
        <Rank>43011</Rank>
      </SalesRank>
      <SalesRank>
        <ProductCategoryId>697342</ProductCategoryId>
        <Rank>36</Rank>
      </SalesRank>
      <SalesRank>
        <ProductCategoryId>3967</ProductCategoryId>
        <Rank>53</Rank>
      </SalesRank>
      <SalesRank>
        <ProductCategoryId>4013</ProductCategoryId>
        <Rank>83</Rank>
      </SalesRank>
    </SalesRankings>
  </Product>
</GetMatchingProductResult>
<ResponseMetadata>
  <RequestId>440cdde0-fa76-4c48-bdd1-d51a3b467823</RequestId>
</ResponseMetadata>
</GetMatchingProductResponse>
4

3 回答 3

4

我发现“Linq To Xml”更易于使用

var xDoc = XDocument.Parse(xml); //or XDocument.Load(filename);
XNamespace ns = "http://mws.amazonservices.com/schema/Products/2011-10-01";
var items = xDoc.Descendants(ns + "ItemAttributes")
                .Select(x => new
                {
                    Author = x.Element(ns + "Author").Value,
                    Brand = x.Element(ns + "Brand").Value,
                    Dimesions = x.Element(ns+"ItemDimensions").Descendants()
                                 .Select(dim=>new{
                                     Type = dim.Name.LocalName,
                                     Unit = dim.Attribute("Units").Value,
                                     Value = dim.Value
                                 })
                                .ToList()

                })
                .ToList();
于 2012-10-23T12:17:53.867 回答
2

您还没有明确明确您需要从 XML 中得到什么,所以我无法给您一个客观的答案。我将首先说明使用 .Net 解析 XML 有许多不同的方法(在您的情况下是 C#,尽管它们与 VB 和 C# 相似)。

我要研究的第一个实际上是将您的 XML 数据建模为 .Net 对象,更具体地说,是 POCO。您可以向该类模型添加将它们绑定或关联到 XML 的属性,然后您需要做的就是将数据和类传递给 XML 反序列化器。

现在,如果您不需要检索整个对象,您可以使用 XDocument 或 XmlDocument。XDocument 的有趣之处在于它对 LINQ 的语法友好,因此您可以非常简单地解析 XML。

XmlDocument 是更老式的顺序方法调用,但实现了同样的事情。


让我来说明一下。为了简单起见,考虑一个更简单的 XML:

<body> 
    <h1>This is a text.</h1>
    <p class="SomeClass">This is a paragraph</p>
</body>

(看看我在那里做了什么?那个 HTML 是一个有效的 XML!)

一、使用反序列化器:

首先,您对类进行建模:

[XmlRoot]
public class body
{
    [XmlElement]
    public h1 h1 { get; set; }

    [XmlElement]
    public p p { get; set; }
}

public class h1 
{
    [XmlText]
    public string innerXML { get; set; }
}

public class p 
{
    [XmlAttribute]
    public string id { get; set; }

    [XmlText]
    public string innerXML { get; set; }
}

一旦你有了你的类模型,你就可以调用序列化器。

void Main()
{
    string xml = 
@"<body> 
    <h1>This is a text.</h1>
    <p id=""SomeId"">This is a paragraph</p>
</body>";

    // Creates a stream that reads from the string
    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(xml);
    writer.Flush();
    stream.Position = 0;

    // Check the classes below before proceding.

    XmlSerializer serializer = new XmlSerializer(typeof(body));
    var obj = (body)serializer.Deserialize(stream);


    // Check obj here with the debugger. All fields are filled.

}

二、使用 XDocument

上面的示例编写了一个非常简洁的代码,因为您可以访问所有键入的内容。但是,它需要大量的设置工作,因为您必须对类进行建模。在您的情况下,也许一些更简单的就足够了。假设您要获取 p 元素的属性:

void Main()
{
    string xml = 
@"<body> 
    <h1>This is a text.</h1>
    <p id=""SomeId"">This is a paragraph</p>
</body>";

    // Creates a stream that reads from the string
    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(xml);
    writer.Flush();
    stream.Position = 0;

    // Using XDocument

    var pAttrib = XDocument.Load(stream).Element("body").Element("p").Attribute("id").Value;
    Console.Writeline(pAttrib);
}

很简单吧?你可以做更复杂的事情,把 LINQ 扔在那里......让我们尝试找到 id 名为“SomeId”的元素:

void Main()
{
    string xml = 
@"<body> 
    <h1>This is a text.</h1>
    <p id=""SomeId"">This is a paragraph</p>
</body>";

    // Creates a stream that reads from the string
    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(xml);
    writer.Flush();
    stream.Position = 0;

    // Using XDocument
    var doc = XDocument.Load(stream);

    var found = from body in doc.Elements("body")
                from elem in body.Elements()
                from attrib in elem.Attributes()
                where attrib.Name == "id" && attrib.Value == "SomeId"
                select elem;


    foreach (var e in found) Console.WriteLine(e);
}

希望能帮助到你。

于 2012-10-23T12:04:35.403 回答
2

您可以重新发明轮子,也可以使用亚马逊的轮子(请参阅@George Duckett 的直接链接答案): Amazon Marketplace API

解决您的问题的一个选项:如果您想要一个能够让您使用 xml 文件的工具,我会查看 xsd.exe。 用于 xsd.exe 的 MSDN

该工具能够从 xml 生成类。

否则,您可以从 XDocument 类创建一个解析器,该类将允许您使用 linq 构建解析器,例如他的帖子中提到的 @LB。

于 2012-10-23T12:21:02.047 回答