C # LINQ to XML запрос с повторяющимися именами элементов, которые имеют атрибуты - PullRequest
2 голосов
/ 09 марта 2010
        <Party id="Party_1">
            <PartyTypeCode tc="1">Person</PartyTypeCode>
            <FullName>John Doe</FullName>
            <GovtID>123456789</GovtID>
            <GovtIDTC tc="1">Social Security Number US</GovtIDTC>
            <ResidenceState tc="35">New Jersey</ResidenceState>
            <Person>
                <FirstName>Frank</FirstName>
                <MiddleName>Roberts</MiddleName>
                <LastName>Madison</LastName>                    
                <Prefix>Dr.</Prefix>
                <Suffix>III</Suffix>
                <Gender tc="1">Male</Gender>
                <BirthDate>1974-01-01</BirthDate>
                <Age>35</Age>
                <Citizenship tc="1">United States of America</Citizenship>
            </Person>
            <Address>
                <AddressTypeCode tc="26">Bill Mailing</AddressTypeCode>
                <Line1>2400 Meadow Lane</Line1>
                <Line2></Line2>
                <Line3></Line3>
                <Line4></Line4>
                <City>Somerset</City>
                <AddressStateTC tc="35">New Jersey</AddressStateTC>
                <Zip>07457</Zip>
                <AddressCountryTC tc="1">United States of America</AddressCountryTC>
            </Address>
        </Party>
        <!-- ***********************  -->
        <!--  Insured Information     -->
        <!-- ***********************  -->
        <Party id="Party_2">
            <PartyTypeCode tc="1">Person</PartyTypeCode>
            <FullName>Dollie Robert Madison</FullName>
            <GovtID>123956239</GovtID>
            <GovtIDTC tc="1">Social Security Number US</GovtIDTC>
            <Person>
                <FirstName>Dollie</FirstName>
                <MiddleName>R</MiddleName>
                <LastName>Madison</LastName>
                <Suffix>III</Suffix>
                <Gender tc="2">Female</Gender>
                <BirthDate>1996-10-12</BirthDate>
                <Citizenship tc="1">United States of America</Citizenship>
            </Person>
            <!-- Insured Address -->
            <Address>
                <AddressTypeCode tc="26">Bill Mailing</AddressTypeCode>
                <Line1>2400 Meadow Lane</Line1>
                <City>Somerset</City>
                <AddressStateTC tc="35">New Jersey</AddressStateTC>
                <Zip>07457</Zip>
                <AddressCountryTC tc="1">United States of America</AddressCountryTC>
            </Address>
            <Risk>
                <!-- Disability Begin Effective Date -->
                <DisabilityEffectiveStartDate>2006-01-01</DisabilityEffectiveStartDate>
                <!-- Disability End Effective Date -->
                <DisabilityEffectiveStopDate>2008-01-01</DisabilityEffectiveStopDate>
            </Risk>
        </Party>
        <!-- *******************************  -->
        <!--  Company Information     -->
        <!-- ******************************  -->
        <Party id="Party_3">
            <PartyTypeCode tc="2">Organization</PartyTypeCode>
            <Organization>
                <DTCCMemberCode>1234</DTCCMemberCode>
            </Organization>
            <Carrier>
                <CarrierCode>105</CarrierCode>
            </Carrier>
        </Party>

Вот мой код, который не работает, потому что сторона 3 не содержит FullName, я знаю, что partyelements содержит 3 стороны, если я только верну атрибут name Есть ли способ перебрать каждый тег отдельно?

        var partyElements = from party in xmlDoc.Descendants("Party")
           select new
           {
               Name = party.Attribute("id").Value,
               PartyTypeCode = party.Element("PartyTypeCode").Value,
               FullName = party.Element("FullName").Value,
               GovtID = party.Element("GovtID").Value,
           };

Ответы [ 3 ]

1 голос
/ 09 марта 2010

Как насчет чего-то подобного?(скорее идея / предложение, чем реализация, потому что я не знаю вашу объектную модель)

var parties = xmlDoc.Descendants("Party");
foreach(var party in parties)
{
    int partyTypeCode = party.Element("PartyTypeCode").Value;
    if(partyTypeCode == 1)
    {
        var person = personFactory.Build(party);
        // do something
    }
    else if(partyTypeCode == 2)
    {
        var organization = companyFactory.Build(party);
        // do something
    }
}

В совершенно полиморфном мире у вас просто будет PartyFactory, а не ifили switch заявления, но сторона человека и сторона компании весьма различны.

0 голосов
/ 26 марта 2010

Я чувствую, что решение Ахмеда - путь. Но вот хак, который я придумал. Если «FullName» является единственным отличительным элементом между двумя различными типами партийных узлов, то, я думаю, может работать следующее:

var validParty = xElement.Descendants("Party")
                            .Elements().Where(x => x.Name == "FullName")
                            .Ancestors("Party")
                            .Elements().Where(x => x.Name == "PartyTypeCode")
                            .Ancestors("Party");


 var partyElements = from party in validParty 
            select new
            {
                Name = party.Attribute("id").Value,
                PartyTypeCode = party.Element("PartyTypeCode").Value,
                FullName = party.Element("FullName").Value,
                GovtID = party.Element("GovtID").Value,
            }; 

Вы можете добавить дополнительные отличительные узлы, если они есть, например "PartyTypeCode". Я не уверен насчет производительности этого.

0 голосов
/ 09 марта 2010

Чтобы избежать исключения NullReferenceException при доступе к элементу FullName, вы можете привести его к строке без вызова Value для элемента. Если он не существует, возвращается ноль, в противном случае будет возвращено значение. Затем вы можете проверить на ноль, перебирая результаты.

Изменение: FullName = party.Element("FullName").Value,

Кому: FullName = (string)party.Element("FullName"),

Обновленный запрос будет:

var partyElements = from party in xmlDoc.Descendants("Party")
    select new
    {
        Name = party.Attribute("id").Value,
        PartyTypeCode = party.Element("PartyTypeCode").Value,
        FullName = (string)party.Element("FullName"),
        GovtID = party.Element("GovtID").Value,
    };

Вы можете сделать то же самое для всех элементов, которые могут существовать или не существовать для определенных элементов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...