【问题标题】:update content of XML file based by attributes of an element with C# [closed]使用 C# 根据元素的属性更新 XML 文件的内容 [关闭]
【发布时间】:2016-05-24 12:55:15
【问题描述】:

我有以下 XML 结构的数据文件。没有可用的 SCHEMA 或 DTD。

我希望尝试一个解决方案(脚本)来更新 XML 文件中的内容,在标签之间没有任何字符串表示从上面的行翻译的字符串。

我阅读了另一个 csv 或文本文件中的所有引用,其结构如下:

Filename ; Line ; value in between <source></source> ; value  to be entered in between <translation></translation>

例如<location filename="Student.txt" line="76"/> <source>From</source> <translation></translation>

改成

<location filename="Student.txt" line="76"/> <source>From</source> <translation>Translation of "From"</translation>

节点由其在元素处的两个属性标识,filename=“Studentform.txt”line=“38”。

 <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="en_US">
<context>
    <name>Student</name>
    <message>
        <location filename="Student.txt" line="76"/>
        <source>From</source>
        <translation></translation>
    </message>
</context>
<context>
    <name>Form</name>
    <message>
        <location filename="Studentform.txt" line="38"/>
        <source>Form</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="Studentform.txt" line="653"/>
        <source>WILLKOMMEN</source>
        <translation>WELCOME</translation>
    </message>
</context>

我是 XML 新手,使用 C#/ASP.NET 的经验有限。 我不知道如何处理。在过去的几天里,我学习了正则表达式 (Regex) 和 XML(介绍了 xPath 和 Schema)。

我来自数据背景、Microsoft Excel/VBA、SSRS 和 T-SQL。

我应该如何解决这个问题。请您指导我如何解决上述问题,最终,我应该进一步研究什么来完成它? 是带字符串还是其他的 XSLT 或 C#?

最简单的处理方法是什么?我有两个星期的时间来实现它。

谢谢一百万。

后期编辑:我编的。这是有效的解决方案。最终,我使用LINQ to CSV 将 csv 数据转换为数组。 非常感谢您的指导,stackoverflow。

using LINQtoCSV;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;


namespace XMLUpdater
{

    //Parse csv data to an array, csv data file= "filenName.txt". All files reside in the directory C:\XMLtool\. Make sure it exists or generate it programatically.

    class csvToParse
    {
        [CsvColumn(Name = "filename", FieldIndex = 1)]
        public string filename { get; set; }

        [CsvColumn(Name = "line", FieldIndex = 2)]
        public string line { get; set; }

        [CsvColumn(Name = "source", FieldIndex = 3)]
        public string source { get; set; }

        [CsvColumn(Name = "translation", FieldIndex = 4)]
        public string translation { get; set; }


    }


    class csv_2_xml
    {
      static void Main(string[] args)
 {
     XDocument doc = XDocument.Load(@"C:\XMLtool\Students.xml");
     CsvFileDescription inputFileDescription = new CsvFileDescription
    {
        SeparatorChar = '\t',
        FirstLineHasColumnNames = true,

    };

     CsvContext cc = new CsvContext();

     IEnumerable<csvToParse> csvStream =
     cc.Read<csvToParse>(@"C:\XMLtool\fileName.txt", inputFileDescription);


            foreach (csvToParse item in csvStream)
            {


                XElement student = doc.Descendants("student")
                    .Where(x => (x.Element("location") != null) &&
                        (x.Element("location").Attribute("filename") != null) &&
                        (x.Element("location").Attribute("filename").Value == item.filename) &&
                        (x.Element("location").Attribute("line") != null) &&
                        (x.Element("location").Attribute("line").Value == item.line.ToString())).First();
                XElement translation = student.Element("translation");

                if (translation != null)
                {
                    translation.Value = item.translation;

                }    
           }

            doc.Save(@"C:\XMLtool\Students_modified.xml");

        }
    } 
}

【问题讨论】:

  • 这一切都使用XmlSerializer 类自动完成。您可以简单地创建一个类并将其序列化。它完成了读取和写入文件的所有工作。
  • 我应该学习什么来应用这个? C#(哪些主题)。请指导我,因为我希望从这个问题中学到一些东西,而不是应用复制/粘贴装置。谢谢。
  • 我添加了一个包含示例的答案。
  • Felix,如何从 csv 读取并使用 XmlSerializer 将 csv 中的 值写入 XML 文件?在 1-1.5 周的学习时间内,我应该将哪些学习内容全部粘合起来以使用 C# 掌握该主题。我没有太多时间来完成这些任务。因为实际上我是一些“万事通”,而不是专门的(初级)C# 开发人员。我主要在数据分析领域工作。非常感谢。
  • 我认为读取 csv 文件非常简单。逐行读取所有内容并将其放入可以序列化的对象中。 csv->object->序列化。

标签: c# .net regex xml powershell


【解决方案1】:

试试 xml linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication93
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            XElement message = doc.Descendants("message")
                .Where(x => (x.Element("location") != null) && 
                    (x.Element("location").Attribute("filename") != null) &&
                    (x.Element("location").Attribute("filename").Value  == "Studentform.txt") &&
                    (x.Element("location").Attribute("line") != null) &&
                    (x.Element("location").Attribute("line").Value  == "38")).FirstOrDefault();
            XElement translation = message.Element("translation");
            if(translation != null)
            {
                translation.Value = "Translation of \"From\"";
            }

        }
    }

}

【讨论】:

  • 我应该怎么做才能通过从外部 csv 文件中扫描的循环读取“文件名”、“行”和“翻译”?请驶向一份文件。谢谢
  • 您可以使用对话框来浏览文件夹名称。您需要一些输入数据来提供对 xml 的 TO/FROM 更改列表。是的,它可能来自 csv 文件。如果您要将单词从一种语言翻译成另一种语言,您可能需要使用 Google Language API。
  • 我需要学习什么才能在一周的学习过程中实现从 csv 读取并写入 XML。你能指导我一下吗?问题是我必须在 1-1.5 周内实现该功能(这应该作为一种解决方案,无论采用何种技术。我选择了 C#,因为有了这个机会,我可以证明有时间深入研究 C#)。感谢您的任何建议。
  • 我不知道您的所有要求。很难通过对您提供的少量信息进行逆向工程来设计系统..
  • 我如何关联 (x.Element("location").Attribute("line").Value == "38")) 和 (x.Element("location").Attribute( "filename").Value == "Studentform.txt") 与解析 csv 产生的数组?我的意思是“38”和“Studentform.txt”的值,它们是必须进行修改的节点的坐标。
【解决方案2】:

如果你知道xml的数据结构。您可以创建一个数据类,然后使用 XmlSerializer 将 xml 转换为对象。 Alter 将对象转换回 xml

Convert Xml with a lot of levels to one DataTable

    public static string ToXMLString(object item)
    {
        var stringwriter = new System.IO.StringWriter();
        var serializer = new XmlSerializer(item.GetType());
        serializer.Serialize(stringwriter, item);
        return stringwriter.ToString();
    }

【讨论】:

    【解决方案3】:

    我在这里整理了一些简单的代码片段作为示例。您需要对其进行修改以满足您的需求。有关此库的更多详细信息,请参阅XmlSerializer

    创建一个类和集合来保存你想要序列化的对象:

    public class Context
    {
       public string Location {get;set;}
       public string Name {get;set;}
       public string Source {get;set;}
       public string Translation {get;set;}
    
    }
    

    现在您可以拥有Context 项的集合。让我们将其设为List&lt;Context&gt;

    List<Context> listOfItems = new List<Context>();
    
    var item = new Context();
    item.Name = "Student";
    item.Location = "Student.txt";
    listOfItems.Add(item);
    

    填充和操作列表后,您可以使用XmlSerializer 将列表写入文件,如下所示:

    public void SaveFileXML(string filePath, List<Context> itemList)
    {
                using (var stream = new FileStream(filePath, FileMode.OpenOrCreate))
                {
                    try
                    {
                        var format = new XmlSerializer(typeof(List<Context>));                    
                        format.Serialize(stream, itemList);
                    }
                    catch (InvalidOperationException exc)
                    {
                        //Handle error
                    }    
                }    
    }
    

    类似地,阅读文档是这样的:

    public List<Context> ReadXml(string filePath)
    {
                List<Context> result = null;
                using (var stream = new FileStream(filePath, FileMode.OpenOrCreate))
                {    
                    try
                    {
                        var format = new XmlSerializer(typeof(List<Context>));
                       // deserialize returns an object so it must be cast.
                        result = format.Deserialize(stream) as List<Context>;
    
                    }
                    catch (InvalidOperationException exc)
                    {
                        //Handle error
                    }
                }
                return result;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-18
      • 1970-01-01
      • 1970-01-01
      • 2020-05-31
      • 1970-01-01
      • 2015-03-17
      • 2021-10-08
      • 1970-01-01
      相关资源
      最近更新 更多