为什么XmlDocument声明变量A修改了B XmlDocument声明的变量时发生更改?

问题描述 投票:0回答:2

我收到一个基本的XML文件,我需要创建N个具有不同内容值的XmlFiles。基本上我会一个副本,更改一些节点值并创建新文件,而无需修改基础文件。

我将每个XML文档添加到文档列表中,以执行其他处理,然后进行交互并创建N个文件。我的代码执行后,我得到的所有文件都具有相同的信息,即使是基础文件也被修改了。我创建一个基本代码来演示它。感谢您对它为什么发生的任何解释。

    // file1.xml
<?xml version="1.0" encoding="UTF-16"?>
<BOM>
    <BO>
        <AdmInfo>
            <Object>2</Object>
            <Version>2</Version>
        </AdmInfo>
        <BusinessPartners>
            <row>
                <CardCode>111111</CardCode>
                <CardName>MADERAS DE AGUADULCE, S.A</CardName>
                <GroupCode>P-Locales</GroupCode>
            </row>
        </BusinessPartners>

    </BO>
</BOM>
// C# code - method that change the value into the xmlFile.
     public XmlDocument ChangeValues(XmlDocument document, List<Tuple<string, string>> AtriValues )
        {

            XmlDocument NewXMLDocument = new XmlDocument();
            // pass the content to another XmlDocument 

            NewXMLDocument = document;

            foreach (var Atribute in AtriValues)
            {
                XmlElement root = NewXMLDocument.DocumentElement;
                XmlNodeList elemList = root.GetElementsByTagName(Atribute.Item1.ToString());
                IEnumerator ienum = elemList.GetEnumerator();
                while (ienum.MoveNext())
                {
                    XmlNode title = (XmlNode)ienum.Current;
                    // Console.WriteLine(title.InnerText);
                    title.InnerText = Atribute.Item2.ToString();

                    //xn[Atribute.Item1.ToString()].InnerText = Atribute.Item2.ToString();
                }
            }

            return NewXMLDocument;
        }
    // C# code- the main prg
static void Main(string[] args)
        {
            Util2 Util = new Util2();
            List<XmlDocument> Documents = new List<XmlDocument>();
            XmlDocument  xmlDocument = new XmlDocument();



            // load the XML file 
            xmlDocument.Load(@"C:\WIP\BaSe\TEST\file1.xml");

            // Save the base file 
            Documents.Add(xmlDocument);

            // Change the content of the document to create document A

            List<Tuple<string, string>> AtriValuesA = new List<Tuple<string, string>>();

            AtriValuesA.Add(new Tuple<string, string>("CardCode", "9999"));
            AtriValuesA.Add(new Tuple<string, string>("GroupCode", "AA"));

            Documents.Add(Util.ChangeValues(xmlDocument, AtriValuesA));




            // Change the content of the document to create document B

            List<Tuple<string, string>> AtriValuesB = new List<Tuple<string, string>>();

            AtriValuesB.Add(new Tuple<string, string>("CardCode", "2222"));
            AtriValuesB.Add(new Tuple<string, string>("GroupCode", "BB"));

            Documents.Add(Util.ChangeValues(xmlDocument, AtriValuesB));


            // get the document and then save then 

            Documents[0].Save(@"C:\WIP\BaSe\TEST\base.xml");
            Documents[1].Save(@"C:\WIP\BaSe\TEST\DOCA.xml");
            Documents[2].Save(@"C:\WIP\BaSe\TEST\DOCB.xml");

        }


c# xmldocument
2个回答
1
投票

所有文件都在更改,因为您正在ChangeValues函数中更改原始xml文档。下面的分配(新文档)无效,因为您正在辅助对原始文档的引用。

XmlDocument NewXMLDocument = new XmlDocument();
// pass the content to another XmlDocument 

NewXMLDocument = document; 

我想到的最快的解决方案是先使用File.Copy函数将原始文件复制到新文件名。之后,只需将新文件加载到文档中并进行更改。

按照您的示例,代码将类似于:

var baseFile = @"C:\WIP\BaSe\TEST\base.xml";

var doc1 =  @"C:\WIP\BaSe\TEST\DOCA.xml";
var doc2 =  @"C:\WIP\BaSe\TEST\DOCB.xml";

File.Copy(baseFile, doc1);
File.Copy(baseFile, doc2);

// you might copy this to other function.

XmlDocument  xmlDocument1 = new XmlDocument();
xmlDocument1.Load(doc1);

Util.ChangeValues(xmlDocument1, AtriValuesA);

xmlDocument1.Save(doc1);

0
投票

当您使用NewXMLDocument = document;时,您正在分配对原始XmlDocument对象的引用,因此所有更改都将应用于原始对象。

代替分配引用,您需要克隆原始对象。我想您想要这样的东西:

public XmlDocument ChangeValues(XmlDocument document, List<Tuple<string, string>> AtriValues )
{
  // Create the new document using the contents of the existing document.
  XmlDocument NewXMLDocument = (XmlDocument)document.CloneNode(true);

  foreach (var Atribute in AtriValues)
  {
    XmlElement root = NewXMLDocument.DocumentElement;
    XmlNodeList elemList = root.GetElementsByTagName(Atribute.Item1.ToString());
    IEnumerator ienum = elemList.GetEnumerator();
    while (ienum.MoveNext())
    {
      XmlNode title = (XmlNode)ienum.Current;
      // Console.WriteLine(title.InnerText);
      title.InnerText = Atribute.Item2.ToString();

      //xn[Atribute.Item1.ToString()].InnerText = Atribute.Item2.ToString();
    }
  }
  return NewXMLDocument;
}

请参见https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmldocument.clonenode

© www.soinside.com 2019 - 2024. All rights reserved.