我正在尝试解析下面给出的xml:
<Item status="SUCCESS" message="">
<ItemDate>12/21/2012
<ItemType>MyType1
<ItemUrl title="ItemTitle">http://www.itemurl1.com</ItemUrl>
</ItemType>
</ItemDate>
<ItemDate>12/22/2012
<ItemType>MyType2
<ItemUrl title="Item2Title">http://www.itemurl2.com</ItemUrl>
</ItemType>
</ItemDate>
</Item>
正如你所看到的,我不确定我们是否可以调用这个xml,但这就是我从遗留服务中得到的东西。我所要解决的是解析它并将其加载到对象图中。我的对象模型如下:
public class Item
{
public string Date { get; set; }
public string Type { get; set; }
public string Url { get; set; }
public string Title { get; set; }
}
所以,基本上当我完成解析上面的xml / string时,我得到一个Item对象的集合。您能否建议我如何通过一些代码片段来实现这一目标?
我尝试过使用XDocument,但考虑到xml的独特结构,我无法做到这一点。
谢谢, -Mike
答案 0 :(得分:2)
XDocument xdoc = XDocument.Load(path_to_xml);
var query = from date in xdoc.Descendants("ItemDate")
let type = date.Element("ItemType")
let url = type.Element("ItemUrl")
select new Item()
{
ItemDate = ((XText)date.FirstNode).Value,
ItemType = ((XText)type.FirstNode).Value,
ItemUrl = (string)url,
ItemTitle = (string)url.Attribute("title"),
};
答案 1 :(得分:1)
作为lazyberezovsky's
Linq2Xml
投影的替代方案,您可能还会考虑在加载Xml之前使用Xml Transform进行展平。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
>
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" />
<xsl:template match="/">
<Items>
<xsl:apply-templates select="Item/ItemDate" />
</Items>
</xsl:template>
<xsl:template match="ItemDate">
<Item>
<xsl:attribute name="ItemDate">
<xsl:value-of select="normalize-space(./text()[1])" />
</xsl:attribute>
<xsl:attribute name="ItemType">
<xsl:value-of select="normalize-space(ItemType/text()[1])" />
</xsl:attribute>
<xsl:attribute name="ItemUrl">
<xsl:value-of select="normalize-space(ItemType/ItemUrl/text()[1])" />
</xsl:attribute>
<xsl:attribute name="ItemTitle">
<xsl:value-of select="normalize-space(ItemType/ItemUrl/@title)" />
</xsl:attribute>
</Item>
</xsl:template>
</xsl:stylesheet>
这会生成以下Xml,它可以直接反序列化,例如:将[XmlAttribute]
attribute与XmlDocument一起使用。
<Items>
<Item ItemDate="12/21/2012" ItemType="MyType1" ItemUrl="http://www.itemurl1.com" ItemTitle="ItemTitle" />
<Item ItemDate="12/22/2012" ItemType="MyType2" ItemUrl="http://www.itemurl2.com" ItemTitle="Item2Title" />
</Items>
答案 2 :(得分:1)
因为在发送的xml中只有一个节点Item,所以你只能得到lazyberezovsky代码中的一个Item。这是正确的。我想你想要获取项目,但是通过ItemDate节点加载它们。为此,请使用以下修改后的代码:
XDocument xdoc = XDocument.Load(new StringReader(xml));
var query = from i in xdoc.Descendants( "ItemDate" )
let date = i
let type = date.Element("ItemType")
let url = type.Element("ItemUrl")
select new Item()
{
Date = ((XText) date.FirstNode).Value,
Type = ((XText) type.FirstNode).Value,
Url = (string) url,
Title = (string) url.Attribute("title"),
};
var items = query.ToList();