使用相同的名称元素解析复杂的XML

时间:2018-02-10 18:58:53

标签: c# xml linq

在使用LINQ解析XML文件时,我一直坚持下一个问题。

总的来说,我当前的问题是我不能将具有相同名称的元素连接到索引元素。当我尝试插入数据库时​​出现问题我获得了更多的行,然后它就是。

应该如何:

uid |          lastName         |                         addressList                                |
-----------------------------------------------------------------------------------------------------|
36  | AEROCARIBBEAN AIRLINES    | Havana Cuba                                                        |
306 | ANGLO-CARIBBEAN CO., LTD. | Zurich Switzerland; Madrid Spain; Tokyo Japan; Panama City Panama; |

我得到了什么:

uid |          lastName         |                         addressList                                |
-----------------------------------------------------------------------------------------------------|
36  | AEROCARIBBEAN AIRLINES    | Havana Cuba                                                        |
306 | ANGLO-CARIBBEAN CO., LTD. | Zurich Switzerland;                                                |
    |                           | Madrid Spain;                                                      |
    |                           | Tokyo Japan;                                                       |
    |                           | Panama City Panama;                                                |

XML:

<root>
<Entry>
    <uid>36</uid>
    <lastName>AEROCARIBBEAN AIRLINES</lastName>
    <sdnType>Entity</sdnType>
    <programList>
        <program>CUBA</program>
    </programList>
    <akaList>
        <aka>
            <uid>12</uid>
            <type>a.k.a.</type>
            <category>strong</category>
            <lastName>AERO-CARIBBEAN</lastName>
        </aka>
    </akaList>
    <addressList>
        <address>
            <uid>25</uid>
            <city>Havana</city>
            <country>Cuba</country>
        </address>
    </addressList>
</Entry>
<Entry>
    <uid>306</uid>
    <lastName>BANCO NACIONAL DE CUBA</lastName>
    <sdnType>Entity</sdnType>
    <programList>
        <program>CUBA</program>
    </programList>
    <akaList>
        <aka>
            <uid>219</uid>
            <type>a.k.a.</type>
            <category>weak</category>
            <lastName>BNC</lastName>
        </aka>
        <aka>
            <uid>220</uid>
            <type>a.k.a.</type>
            <category>strong</category>
            <lastName>NATIONAL BANK OF CUBA</lastName>
        </aka>
    </akaList>
    <addressList>
        <address>
            <uid>199</uid>
            <address1>Zweierstrasse 35</address1>
            <city>Zurich</city>
            <postalCode>CH-8022</postalCode>
            <country>Switzerland</country>
        </address>
        <address>
            <uid>200</uid>
            <address1>Avenida de Concha Espina 8</address1>
            <city>Madrid</city>
            <postalCode>E-28036</postalCode>
            <country>Spain</country>
        </address>
        <address>
            <uid>201</uid>
            <address1>Dai-Ichi Bldg. 6th Floor, 10-2 Nihombashi, 2-chome, Chuo-ku</address1>
            <city>Tokyo</city>
            <postalCode>103</postalCode>
            <country>Japan</country>
        </address>
        <address>
            <uid>202</uid>
            <address1>Federico Boyd Avenue &amp; 51 Street</address1>
            <city>Panama City</city>
            <country>Panama</country>
        </address>
    </addressList>
</Entry>
<root>

我的代码:

XDocument Document = XDocument.Load(@".\FileName.xml");

var RootNode = from row in Document.Root.Elements("Entry") select row;
var AdressNode = from row in Document.Root.Elements("Entry").Descendants("addressList").Descendants("address") select row; 

string[] UIDArray = RootNode.Select(o => (string)o.Element("uid")).ToArray();
string[] FullNameArray = RootNode.Select(o => (string)o.Element("firstName") == null ? (string)o.Element("lastName") : (string)o.Element("firstName") + " " + (string)o.Element("lastName")).ToArray();

// addressList ? concat values?
string[] Test = AdressNode.Select(o => (string)o.Element("country") + " " + (string)o.Element("city") + " " + (string)o.Element("address1")).ToArray();

3 个答案:

答案 0 :(得分:0)

这是因为AdressNode已经填充了5个元素,因此团队达到连接时已经太晚了,因为所有后代都是从顶级“文档”中检索的。

相反,您可以从两个主要父项中的每一个(即每个Entry元素)构建元素。

var RootNode = from row in Document.Root.Elements("Entry") select row;

var output = new List<string>();
foreach (var node in RootNode.ToList())
{
    var AddressNode = from row in node.Descendants("addressList").Descendants("address") select row;
    var element = AddressNode.Select(o => (string)o.Element("country") + " " + (string)o.Element("city") + " " + (string)o.Element("address1")).ToArray();
    output.Add(string.Join(",", element.ToList()));
}

string[] Test = output.ToArray();

答案 1 :(得分:0)

使用GroupBy可能是您正在寻找的解决方案

var groups = AdressNode.GroupBy(x => (string)x.Parent.Parent.Element("uid")).ToList();

List<string> Test = new List<string>();

foreach (var group in groups)
{
    var item = string.Join("; ", group.Select(o => (string) o.Element("country") + " " + (string) o.Element("city") + " " + (string) o.Element("address1")).ToArray());
    Test.Add(item);
}

答案 2 :(得分:0)

Charles Owen,这就是我对单个linq查询

的意思
var result = Document.Descendants("Entry")
            .Select(x => new {
                Uid = (string)x.Element("uid"),
                LastName = (string)x.Element("lastName"),
                AddressList = x.Descendants("address")
                                .Select(y => new {
                                    Uid = (string)y.Element("uid"),
                                    City = (string)y.Element("city"),
                                    Country = (string)y.Element("country"),
                                    Address1 = (string)y.Element("address1"),
                                    PostalCode = (string)y.Element("postalCode")
                                })
                                .ToList()

            })
            .ToList();
相关问题