具有具有属性的重复元素名称的 C# LINQ to XML 查询

发布于 2024-08-24 13:44:00 字数 4466 浏览 4 评论 0原文

        <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,如果我只返回 name 属性,我知道 partyelements 包含 3 个方。有没有办法单独循环每个标签?

        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,
           };
        <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>

Here is my code which doesn't work because party 3 doesn't contain FullName, I know that partyelements contains 3 parties if I only return the name attribute. Is there a way to loop through each tag seperate?

        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,
           };

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心的憧憬 2024-08-31 13:44:01

沿着这些思路怎么样? (更多的是想法/建议而不是实现,因为我不知道你的对象模型)

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 而没有 ifswitch 语句,但个人方和公司方有很大不同。

How about something along these lines? (more of an idea/suggestion than an implementation, because I don't know your object model)

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
    }
}

In a perfectly polymorphic world, you'd just have a PartyFactory and no if or switch statements, but a person party and a company party are quite different.

愛放△進行李 2024-08-31 13:44:01

为了避免在访问 FullName 元素时出现 NullReferenceException,您可以将其转换为字符串,而无需在该元素上调用 Value。如果不存在则返回null,否则返回值。然后,您可以在迭代结果时检查 null 。

更改: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,
    };

您可以对某些项目可能存在或不存在的所有元素执行相同的操作。

To avoid a NullReferenceException when accessing the FullName element you can cast it to a string without calling Value on the element. If it doesn't exist null will be returned, otherwise the value will be returned. You can then check for null while iterating over the results.

Change: FullName = party.Element("FullName").Value,

To: FullName = (string)party.Element("FullName"),

The updated query would be:

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,
    };

You can do the same thing for all elements that may or may not exist for certain items.

空城缀染半城烟沙 2024-08-31 13:44:01

我觉得艾哈迈德的解决方案是可行的。但这是我想出的技巧。如果“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”。我不确定这的性能方面。

I feel Ahmed's solution is the way to go. But here is the hack I came up with. If 'FullName' is the only distinguishing Element between two different types of party nodes then I guess the following may work:

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,
            }; 

You may add additional distinguishing nodes if any like the "PartyTypeCode". I am not sure about the performance aspect of this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文