首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用内部节点解析xml

使用内部节点解析xml
EN

Stack Overflow用户
提问于 2012-12-14 19:40:49
回答 3查看 242关注 0票数 2

我正在尝试解析下面给出的xml:

代码语言:javascript
复制
<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,但这就是我从遗留服务中得到的。我要做的是解析它并将其加载到对象图中。我的对象模型如下:

代码语言:javascript
复制
 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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-14 19:54:05

代码语言:javascript
复制
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"),
            };
票数 2
EN

Stack Overflow用户

发布于 2012-12-14 20:12:54

作为Xml的替代方案,您还可以考虑在加载lazyberezovsky's之前使用Xml Transform进行扁平化。

代码语言:javascript
复制
<?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,它很容易反序列化,例如,使用带有XmlDocument的[XmlAttribute] attribute

代码语言:javascript
复制
<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>
票数 1
EN

Stack Overflow用户

发布于 2012-12-14 20:47:27

因为在发送的xml中只有一次节点项,所以只能从lazyberezovsky的代码中获得一个项。这是正确的。我猜想您想要获取项,但是通过ItemDate节点加载它们。为此,请使用以下修改后的代码:

代码语言:javascript
复制
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();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13878004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档