linq到xml遍历结果

时间:2022-09-23 07:38:11

I'm new to using linq in particular linq to xml and am having trouble trying to iterate through the results. My xml document has multiple nodes of the same name nested in a single parent node and I have used the following linq query which returns the correct result set.

我是新手使用linq特别是linq到xml,我很难尝试迭代结果。我的xml文档有多个同名的节点嵌套在单个父节点中,我使用了以下linq查询,它返回正确的结果集。

var listingAgentElements = from p in _xElement.Descendants("commercial") select p.Elements("listingAgent");

My xml has the following format:

我的xml具有以下格式:

<commercial>
    <listingAgent id="1">
    <listingAgent id="2">
    <listingAgent id="3">
 </commercial>       

I am getting a result set containing all of the listing agents although for some reason when I try do the following foreach loop over listingAgentElements each element I try to loop over seems to have exactly the same result set as in still has all three listingAgents:

我得到一个包含所有列表代理的结果集,虽然由于某种原因,当我尝试对listingAgentElements执行以下foreach循环时,我尝试循环的每个元素似乎具有完全相同的结果集,仍然具有所有三个listingAgents:

foreach (var element in listingAgentElements)
{
    var test = element;
}

Each listingAgent has a set of child elements in which I would like to loop over and get the values of to store in a DB as I'm doing an xml import console app.

每个listingAgent都有一组子元素,我想循环并获取存储在数据库中的值,因为我正在做一个xml导入控制台应用程序。

It appears that their may be a problem with the query but I'm really not sure, could someone please assist?

看来他们可能是查询的问题,但我真的不确定,有人可以帮忙吗?

2 个解决方案

#1


0  

Ok so from what you've posted, it looks like your listingAgentElements actually contains 2 enumerables - one comes from _xElement.Descendants("commercial") (even if there's only one, .Descendants returns an enumerable list), and the second from .Elements("listingAgent")

好吧,根据你发布的内容,看起来你的listingAgentElements实际上包含2个枚举 - 一个来自_xElement.Descendants(“commercial”)(即使只有一个,.Descendants返回一个可枚举列表),第二个来自。元素( “listingAgent”)

I'd hazard a guess and say that from the XML you posted, your for loop is only running through once? This means it's looping through the enumerable for _xElement.Descendants and hence commercial is actually another enumerable containing all 3 listingAgents.

我猜错了,并说你发布的XML,你的for循环只运行一次?这意味着它循环遍历_xElement.Descendants的枚举,因此商业实际上是另一个包含所有3个listingAgent的可枚举。

If your XML only has one "commercial" tag, I'd get that using .Element("commercial"), or if it's the root of your XElement object then don't even bother with that part.

如果您的XML只有一个“商业”标签,我会使用.Element(“commercial”),或者如果它是您的XElement对象的根,那么甚至不打扰该部分。

So the options are: If you just have one "commercial" tag, and your _xElement is in fact an XElement representing this, use:

所以选项是:如果你只有一个“商业”标签,并且你的_xElement实际上是一个代表这个的XElement,请使用:

   var listingAgentElements =  from p in _xElement
                               select p.Elements("listingAgent");

If you have one "commercial" tag but it is not the root of your _xElement then use:

如果你有一个“商业”标签,但它不是_xElement的根,那么使用:

   var listingAgentElements =  from p in _xElement.Element("commercial")
                               select p.Elements("listingAgent");

If you just have one "commercial" tag, and your _xElement is actually an XDocument , use:

如果您只有一个“商业”标记,并且您的_xElement实际上是一个XDocument,请使用:

   var listingAgentElements =  from p in _xElement.Root
                               select p.Elements("listingAgent");

If you have multiple "commercial" tags, use the original query but loop over it twice, for example:

如果您有多个“商业”标记,请使用原始查询,但循环两次,例如:

    foreach (var commercial in listingAgentElements)
    {
        foreach (var element in commercial)
        {
            var test = element;
        }
    }

One of these solutions should provide you with a list of the listingAgents you require. If you need any clarification post a comment and I'll edit the answer as necessary.

其中一个解决方案应该为您提供所需的listingAgent列表。如果您在发表评论时需要任何澄清,我会根据需要编辑答案。

As an aside, I'd look at the formatting of your XML - if you've copy/pasted this, you need to be closing your listingAgent tags, with either <listingAgent id="1" /> or <listingAgent id="1"></listingAgent>. Now you did mention that your listingAgent contains more tags, so I'm assuming you've just cut the code down to post only the relevant parts, but just something you might need to keep an eye on. (If you're using Linq2XML to create your XMLs, this will be handled automatically anyway).

顺便说一下,我会查看XML的格式 - 如果你复制/粘贴了这个格式,你需要关闭你的listingAgent标签,其中 。现在你确实提到你的listingAgent包含更多标签,所以我假设你只是将代码剪下来只发布相关部分,但只是你可能需要关注的东西。 (如果您使用Linq2XML创建XML,则无论如何都会自动处理)。

#2


0  

Use SelectMany to flatten IEnumerable<IEnumerable<XElement>> to IEnumerable<XElement>:

使用SelectMany将IEnumerable >压缩为IEnumerable :

var listingAgentElements =  from p in _xElement.Descendants("commercial")
                            from l in p.Elements("listingAgent")
                            select l;

Or in method-based syntax:

或者基于方法的语法:

var listingAgentElements = _xElement.Descendants("commercial")
                                    .SelectMany(p => p.Elements("listingAgent");

Iterating over that kind of query results will give you all <listingAgent> elements.

迭代这种查询结果将为您提供所有 元素。

#1


0  

Ok so from what you've posted, it looks like your listingAgentElements actually contains 2 enumerables - one comes from _xElement.Descendants("commercial") (even if there's only one, .Descendants returns an enumerable list), and the second from .Elements("listingAgent")

好吧,根据你发布的内容,看起来你的listingAgentElements实际上包含2个枚举 - 一个来自_xElement.Descendants(“commercial”)(即使只有一个,.Descendants返回一个可枚举列表),第二个来自。元素( “listingAgent”)

I'd hazard a guess and say that from the XML you posted, your for loop is only running through once? This means it's looping through the enumerable for _xElement.Descendants and hence commercial is actually another enumerable containing all 3 listingAgents.

我猜错了,并说你发布的XML,你的for循环只运行一次?这意味着它循环遍历_xElement.Descendants的枚举,因此商业实际上是另一个包含所有3个listingAgent的可枚举。

If your XML only has one "commercial" tag, I'd get that using .Element("commercial"), or if it's the root of your XElement object then don't even bother with that part.

如果您的XML只有一个“商业”标签,我会使用.Element(“commercial”),或者如果它是您的XElement对象的根,那么甚至不打扰该部分。

So the options are: If you just have one "commercial" tag, and your _xElement is in fact an XElement representing this, use:

所以选项是:如果你只有一个“商业”标签,并且你的_xElement实际上是一个代表这个的XElement,请使用:

   var listingAgentElements =  from p in _xElement
                               select p.Elements("listingAgent");

If you have one "commercial" tag but it is not the root of your _xElement then use:

如果你有一个“商业”标签,但它不是_xElement的根,那么使用:

   var listingAgentElements =  from p in _xElement.Element("commercial")
                               select p.Elements("listingAgent");

If you just have one "commercial" tag, and your _xElement is actually an XDocument , use:

如果您只有一个“商业”标记,并且您的_xElement实际上是一个XDocument,请使用:

   var listingAgentElements =  from p in _xElement.Root
                               select p.Elements("listingAgent");

If you have multiple "commercial" tags, use the original query but loop over it twice, for example:

如果您有多个“商业”标记,请使用原始查询,但循环两次,例如:

    foreach (var commercial in listingAgentElements)
    {
        foreach (var element in commercial)
        {
            var test = element;
        }
    }

One of these solutions should provide you with a list of the listingAgents you require. If you need any clarification post a comment and I'll edit the answer as necessary.

其中一个解决方案应该为您提供所需的listingAgent列表。如果您在发表评论时需要任何澄清,我会根据需要编辑答案。

As an aside, I'd look at the formatting of your XML - if you've copy/pasted this, you need to be closing your listingAgent tags, with either <listingAgent id="1" /> or <listingAgent id="1"></listingAgent>. Now you did mention that your listingAgent contains more tags, so I'm assuming you've just cut the code down to post only the relevant parts, but just something you might need to keep an eye on. (If you're using Linq2XML to create your XMLs, this will be handled automatically anyway).

顺便说一下,我会查看XML的格式 - 如果你复制/粘贴了这个格式,你需要关闭你的listingAgent标签,其中 。现在你确实提到你的listingAgent包含更多标签,所以我假设你只是将代码剪下来只发布相关部分,但只是你可能需要关注的东西。 (如果您使用Linq2XML创建XML,则无论如何都会自动处理)。

#2


0  

Use SelectMany to flatten IEnumerable<IEnumerable<XElement>> to IEnumerable<XElement>:

使用SelectMany将IEnumerable >压缩为IEnumerable :

var listingAgentElements =  from p in _xElement.Descendants("commercial")
                            from l in p.Elements("listingAgent")
                            select l;

Or in method-based syntax:

或者基于方法的语法:

var listingAgentElements = _xElement.Descendants("commercial")
                                    .SelectMany(p => p.Elements("listingAgent");

Iterating over that kind of query results will give you all <listingAgent> elements.

迭代这种查询结果将为您提供所有 元素。