代码之家  ›  专栏  ›  技术社区  ›  Spence

更改C中元素值的最佳方法#

  •  13
  • Spence  · 技术社区  · 16 年前

    我试图寻找在XML中更改元素值的最佳方法。

    <MyXmlType>
       <MyXmlElement>Value</MyXmlElement>
    </MyXmlType>
    

    更改c_中“值”的最简单和/或最佳方法是什么?

    我已经看过xml document,它将导致整个XML文档被加载到内存中。你能用XML阅读器安全地做到这一点吗?问题是改变价值并将其释放回去似乎是一个有趣的难题。

    干杯:D

    9 回复  |  直到 6 年前
        1
  •  30
  •   Tassisto Nidheesh    9 年前

    您可以使用system.xml.linq名称空间材料来获得最容易读取的代码。这将把整个文件加载到内存中。

    XDocument xdoc = XDocument.Load("file.xml");
    var element = xdoc.Elements("MyXmlElement").Single();
    element.Value = "foo";
    xdoc.Save("file.xml");
    
        2
  •  5
  •   Andrew Ensley    16 年前

    编辑:没有看到关于xmldocument的子句。xmlReader就是这样做的。不能用此类编辑XML文件。

    你想要XML编写器。但是,如果它仍然有用,这里是xmldocument的代码。

    private void changeXMLVal(string element, string value)
    {
        try
        {
            string fileLoc = "PATH_TO_XML_FILE";
            XmlDocument doc = new XmlDocument();
            doc.Load(fileLoc);
            XmlNode node = doc.SelectSingleNode("/MyXmlType/" + element);
            if (node != null)
            {
                node.InnerText = value;
            }
            else
            {
                XmlNode root = doc.DocumentElement;
                XmlElement elem;
                elem = doc.CreateElement(element);
                elem.InnerText = value;
                root.AppendChild(elem);
            }
            doc.Save(fileLoc);
            doc = null;
        }
        catch (Exception)
        {
            /*
             * Possible Exceptions:
             *  System.ArgumentException
             *  System.ArgumentNullException
             *  System.InvalidOperationException
             *  System.IO.DirectoryNotFoundException
             *  System.IO.FileNotFoundException
             *  System.IO.IOException
             *  System.IO.PathTooLongException
             *  System.NotSupportedException
             *  System.Security.SecurityException
             *  System.UnauthorizedAccessException
             *  System.UriFormatException
             *  System.Xml.XmlException
             *  System.Xml.XPath.XPathException
            */
        }
    }
    
        3
  •  2
  •   Rex M    16 年前

    您可以使用xmlReader读取到一个类中,该类通过xmlWriter将数据泵出,并在读/写之间扫描元素,根据需要更改该值。

    说实话,我有点惊讶你的XML文件这么大,你担心内存消耗…不说这从来都不是问题。如果没有更多的信息,我不能说您假设的XML文件不是50GB,但是在许多情况下,将看起来大到足以操作的文件加载到内存中并没有您想象的那么大。

        4
  •  2
  •   Vin    16 年前

    您考虑过使用linq-to-xml吗?(如果您使用的是.NET 3.0+)

    public static XElement ChangeValue(string xmlSnippet, 
        string nodeName,
        string newValue)
    {
        XElement snippet = XElement.Parse(xmlSnippet);
        if (snippet != null)
        {
            snippet.Element(nodeName).Value = newValue;
        }
        return snippet;
    }
    

    我猜Xelement的性能会比XMLDocument好(尽管不确定),Xelement的基对象是XObject,是的,它必须加载整个文档。

        5
  •  2
  •   Community CDub    8 年前

    使用仅向前读卡器肯定是最有效的方法,在这种情况下,XML读卡器派生似乎是合适的,尽管它比使用一次性加载整个文件的DOM方法更有效。

    XMLRead被认为是对起源于Java世界的SAXXML解析器API的改进,但它已经成为业界的阿德事实标准(微软之外)。

    如果您只想快速完成任务,那么xmlTextReader就是为此目的而存在的(在.NET中)。

    如果您想学习一个稳定的事实上的标准(在许多编程语言中也可以使用),这将迫使您非常高效、优雅地编写代码,但这也是非常灵活的,那么请看SAX。 但是,不要为SAX本身操心,除非您要创建非常深奥的XML解析器。外面有很多解析器在封面下使用SAX。

    请结账离开 我对SAX的回应这里列出了SAX资源和真正的创造性 .NET XML解析器概念 它使用XMLTRealDADER作为其基础: SAX vs XmlTextReader - SAX in C#

        6
  •  2
  •   jonsca    12 年前

    这将使用一个旧文件并创建一个具有更新值的新文件。如果找不到元素,它将引发异常

    {
        XDocument newSettingFile =  new XDocument(settingFile);
        //Root element
        var newSetting = newSettingFile.Element("MyXmlType");
        //Update childelement with new value
        newSetting.Element("MyXmlElement").Value = "NewValue";   
        return newSettingFile;
    }
    
        7
  •  1
  •   ItsAllABadJoke    9 年前

    我对一个10.6 k的文档进行了一些测试。解析XML文档的速度总是比Linq查询快50%。

           var stopwatch2 = Stopwatch.StartNew();
            XmlDocument xd = new XmlDocument();
            xd.LoadXml(instanceXML);
            XmlNode node = xd.SelectSingleNode("//figures/figure[@id='" + stepId + "']/properties/property[@name='" + fieldData + "']");
                node.InnerXml = "<![CDATA[ " + valData + " ]]>";  
            stopwatch2.Stop();
            var xmlDocTicks = stopwatch2.ElapsedTicks;
    
            Stopwatch stopwatch1 = Stopwatch.StartNew(); 
            XDocument doc = XDocument.Parse(instanceXML);
            XElement prop =
            (from el in doc.Descendants("figure")
             where (string)el.Attribute("id") == stepId
                select el).FirstOrDefault();
            prop.Value = valData;
            stopwatch1.Stop();
            var linqTicks = stopwatch1.ElapsedTicks;
    

    结果如下(xmldocticks、linqticks):

    • 运行1:(12581581)
    • 运行2:(26673463)
    • 运行3:(14162626)
    • 运行4:(12312383)
    • 平均:(16432513)
        8
  •  1
  •   Dekker    9 年前
    using System;
    using System.Xml;
    using System.Linq;
    using System.Xml.Linq;
    
    namespace ReandAndWriteXML
    {
        class MainClass
        {
            public static void Main (string[] args)
            {
                XDocument xdoc = XDocument.Load(@"file.xml");
                var element = xdoc.Root.Elements("MyXmlElement").Single();
                element.Value = "This wasn't nearly as hard as the internet tried to make it!";
                xdoc.Save(@"file.xml");
            }
        }
    }
    

    这很像本·罗宾的例子,只是它起作用了(尽管他的也起作用了,现在已经被编辑了)。我甚至给了你使用指令!

        9
  •  0
  •   Minute V    6 年前

    加载与保存

    public XDocument XDocument { get; set; }
        private async Task OpenResWFileAsync()
        {
            List<XElement> dataElements;
            var reswFile = await StorageHelper.PickSingleFileAsync(".resw");
            if (reswFile == null) return;
            using (Stream fileStream = await reswFile.OpenStreamForReadAsync())
            {
                this.XDocument = XDocument.Load(fileStream);
                dataElements = this.XDocument.Root.Elements("data").ToList();
                this.DataElements = dataElements;
            }
        }
        #region
        private List<string> GetValues()
        {
            if (this.XDocument == null) return new List<string>();
            return this.XDocument.Root.Elements("data").Select(e => e.Attribute("name").Value).ToList();
    
        }
        public void ChangeValue(string resourceKey, string newValue)
        {
            if (this.DataElements == null) return;
            var element = this.DataElements.Where(e => e.Name == resourceKey).Single();
            element.Value = newValue;
        }
        #endregion