使用Xml To Linq在C#中创建Xml文件

时间:2010-06-28 09:13:11

标签: c# xml

我有一个xml文件(Sample.xml),它具有以下结构

 <Root>
    <Child ChildName="Ms_7">
            <MissingSiblings>
                <Sibling SiblingName="47" />
            </MissingSiblings>
    </Child>
    <Child ChildName="Ms_8">
            <MissingSiblings>
                 <Sibling SiblingName="P2" />
            </MissingSiblings>
     </Child>
     <Child ChildName="Ms_9">
            <MissingSiblings>
                 <Sibling SiblingName="T2" />
            </MissingSiblings>
    </Child>
    <Child ChildName="Ms_10">
            <MissingSiblings>
                <Sibling SiblingName="R3" />
            </MissingSiblings>
    </Child>
    <Child ChildName="Additional_SIB1">
            <AdditionalSiblings>
                 <Sibling SiblingName="92" />
                 <Sibling SiblingName="93" />
            </AdditionalSiblings>
        <MissingSiblings>
                <Sibling SiblingName="S3" />
            </MissingSiblings>
    </Child>
    <Child ChildName="Additional_SIB2">
            <AdditionalSiblings>
                <Sibling SiblingName="39" />
                <Sibling SiblingName="34" />
            </AdditionalSiblings>
    </Child>  
</Root>

我需要从Sample.xml文件更新另一个xml文件(Result.xml)。  像

<Root>
    <Step Name="Step1" Date="06/12/2010" Value="">
        <Test Name="Ms_7" AdditionalSibling="" MissingSibling="47"/>
        <Test Name="Ms_8" AdditionalSibling="" MissingSibling="P2"/>
        <Test Name="Ms_9" AdditionalSibling="" MissingSibling="T2"/>
        <Test Name="Ms_10" AdditionalSibling="" MissingSibling="R3"/>
        <Test Name="SIB1" AdditionalSibling="92,93" MissingSibling="S3"/>
        <Test Name="SIB2" AdditionalSibling="39,34" MissingSibling=""/>
    </Step>
</Root>

现在我正在使用:

1)迭代Sample.xml文件的内容

2)检查“ChildName”是否包含“Additional”

a)暂时删除

3)迭代子节点

4)如果有多个孩子附加逗号(,)

代码如下:

        XmlDocument SampleDoc = new XmlDocument();
        XmlDocument ResultDoc = new XmlDocument();

        SampleDoc.Load(Application.StartupPath + "\\Sample.xml");
        ResultDoc.Load(Application.StartupPath + "\\Result.xml");
        XmlElement ResultRoot = ResultDoc.DocumentElement;
        XmlElement RsNxt = (XmlElement)ResultDoc.SelectSingleNode("//Step[@Name='Step222']");
        if (RsNxt == null)
            RsNxt=ResultDoc.CreateElement("Step");
        else
            RsNxt.RemoveAll();
        RsNxt.SetAttribute("Name", "Step1");
        RsNxt.SetAttribute("Date", DateTime.Now.ToString());
        RsNxt.SetAttribute("Value", "");
        String l_strName = "";
        XmlNodeList ChildList = SampleDoc.SelectNodes("//Root/Child");
        if (ChildList.Count > 0)
        {
            foreach (XmlNode child in ChildList)
            {
                XmlElement ChildElement = (XmlElement)child;
                l_strName = ChildElement.GetAttribute("ChildName");

                bool l_bvalue = l_strName.Contains("Additional");
                int l_ntemp = 0;
                XmlNodeList l_List = null;
                String l_strAdd = "";
                String l_strMissing = "";

                String l_strAdditional = l_strName;
                if (l_bvalue == true)
                    l_strAdditional = l_strName.Substring(l_strName.IndexOf('_') + 1);

                XmlElement Test = ResultDoc.CreateElement("Test");
                Test.SetAttribute("Name", l_strAdditional);
                if (l_bvalue == false)
                {
                    l_List = ChildElement.SelectNodes("//Child[@ChildName='" + l_strName + "']/MissingSiblings/Sibling"); 

                    l_ntemp = 0;
                    String l_strMissingSibling = "";
                    foreach (XmlNode l_missingS in l_List)
                    {
                        XmlElement Element = (XmlElement)l_missingS;
                        l_strMissingSibling = Element.GetAttribute("SiblingName");
                        l_ntemp += 1;
                        if (l_ntemp == 1)
                            l_strMissing = l_strMissingSibling;
                        if (l_ntemp > 1)
                        {
                            l_strMissing += ',' + " ";
                            l_strMissing += l_strMissingSibling;
                        }
                    }
                }
                else
                {
                    l_List = ChildElement.SelectNodes("//Child[@ChildName='" + l_strName +"']/AdditionalSiblings/Sibling");
                    l_ntemp = 0;
                    String l_strAddSibling = "";
                    foreach (XmlNode Additional in l_List)
                    {
                        XmlElement nodeElement = (XmlElement)Additional;
                        l_strAddSibling = nodeElement.GetAttribute("SiblingName");
                        l_ntemp += 1;
                        if (l_ntemp == 1)
                            l_strAdd = l_strAddSibling;
                        if (l_ntemp > 1)
                        {
                            l_strAdd += ',' + " ";
                            l_strAdd += l_strAddSibling;
                        }
                    }
                }
                Test.SetAttribute("AdditionalSiblings", l_strAdd);
                Test.SetAttribute("MissingSiblings", l_strMissing);
                RsNxt.AppendChild(Test);
            }

        }
        ResultRoot.AppendChild(RsNxt);
        ResultDoc.Save(Application.StartupPath + "\\Result.xml");

还有其他方法可以像Xml到Linq approch那样做吗?

先谢谢

1 个答案:

答案 0 :(得分:1)

使用Linq to XML肯定可以简化这一点。我为你的案例写了一个简短的例子,你需要添加一些细节(比如处理失踪的兄弟姐妹),但它应该给你一个想法。 XDocument doc应包含原始XML。

XDocument newDoc = new XDocument(new XElement("step"));
foreach (XElement child in doc.Root.Elements())
{
    XElement entry = new XElement("Test");
    entry.SetAttributeValue("Name", child.Attribute("ChildName")
                                         .Value.Replace("Additional_", ""));

    if (child.Elements("AdditionalSiblings").Count() > 0)
    {
        entry.SetAttributeValue("AdditionalSibling",
            child.Elements("AdditionalSiblings").Elements()
                                                .Select(xe => xe.Attribute("SiblingName").Value)
                                                .Aggregate((s1,s2) => s1+","+s2));
    }
    else
    {
        entry.SetAttributeValue("AdditionalSibling", "");
    }
    newDoc.Root.Add(entry);

}