在XML C#

时间:2018-05-10 07:45:05

标签: c# xml

我有一个看起来像这样的XML,

<Names>
    <Name>
        <FName>Abc</FName>
        <LName>XYZ</LName>
    </Name>
    <Name>
        <FName>Abc2</FName>
        <LName>XYZ2</LName>
    </Name>
    <Name>
        <FName>Abc3</FName>
        <LName>XYZ3</LName>
    </Name>
    <Name>
        <FName>Abc4</FName>
        <LName>XYZ4</LName>
    </Name>
</Names>

我试图在c#中预先更改节点名称,如果它们的出现不止一次并且除了第一个节点。第一个节点名称保持不变;

处理完XML后应该是这样的;

<Names>
    <Name> // kepp first node name same
        <FName>Abc</FName>
        <LName>XYZ</LName>
    </Name>
    <ChildName> //changed
        <FName>Abc2</FName>
        <LName>XYZ2</LName>
    </ChildName>
    <ChildName> //changed
        <FName>Abc3</FName>
        <LName>XYZ3</LName>
    </ChildName>
    <ChildName> // changed
        <FName>Abc4</FName>
        <LName>XYZ4</LName>
    </ChildName>
</Names>

Name的节点可以是1,如果是一次,保持不变,如果超过第一个并更改其他名称。

我想这个XML对象是IEnumerable<XElement>类型;

//check if NAME node occurs multiple times, make other to child.
var nameCounts = element.Descendants().Where(x => x.Name.LocalName == "Name");
int number = nameCounts.Count();
if (number > 1) // if occurance more than one
{
    foreach (var e in element.Descendants().Where(x => x.Name.LocalName == "Name").ToList())
    {
        //e.NodesAfterSelf();
        // unable to understand what to do
    }
}

更新:

但是我得到了我的问题的答案;我犯了一个小错误,实际上我的XML看起来像这样;

<ListOfNames>
    <Names>
        <Name> // two occurrence, 2nd will change to CHILD NAME
            <FName>Abc</FName>
            <LName>XYZ</LName>
        </Name>
        <Name>
            <FName>Abc2</FName>
            <LName>XYZ2</LName>
        </Name>
    </Names>
    <Names> // three occurrence,  2nd and 3rd will change to CHILDNAME
        <Name>
            <FName>Abc</FName>
            <LName>XYZ</LName>
        </Name>
        <Name>
            <FName>Abc2</FName>
            <LName>XYZ2</LName>
        </Name>
        <Name>
            <FName>Abc2</FName>
            <LName>XYZ2</LName>
        </Name>
    </Names>
    <Names> // only one occurrence, nothing change
        <Name>
            <FName>Abc</FName>
            <LName>XYZ</LName>
        </Name>
    </Names>
</ListOfNames>

1 个答案:

答案 0 :(得分:3)

它比你现在制作它简单。您需要做的就是跳过第一个Name元素,并更改其余元素的名称。要处理多个Names元素,只需查找具有doc.Descendants("Names")的每个元素,然后处理该容器中的元素。

以下是完全相同的代码:

using System;
using System.Linq;
using System.Xml.Linq;

public class Test
{
    public static void Main(string[] args)
    {
        var doc = XDocument.Load("test.xml");

        // Handle each Names element separately
        foreach (var container in doc.Descendants("Names"))
        {
            // Within a names element, find all the Name elements,
            // and materialize the query. (That may not be necessary; see later.)
            var names = container.Elements("Name").ToList();

            // Skip the first name, but modify each of the rest.
            foreach (var element in names.Skip(1))
            {
                element.Name = "ChildName";
            }
        }
        Console.WriteLine(doc);
    }
} 

ToList()调用可能没有必要。对于在迭代查询时对文档所做的更改是否有问题,LINQ to XML并不是非常清楚(对我而言)。我当然看到我希望出现问题的情况,但确实会引起问题 - 反之亦然。如果您知道您的文档足够小以至于实现结果实际上不会导致问题,我通常会这样做以避免进一步调查。

相关问题