简体   繁体   English

使用 OpenXML C# 编辑 CustomXML

[英]Edit CustomXML with OpenXML C#

This is my first OpenXML project.这是我的第一个 OpenXML 项目。 I am trying to edit the CustomXML file of a docx file.我正在尝试编辑 docx 文件的 CustomXML 文件。 I am trying to change this:我正在尝试改变这一点:

      <?xml version="1.0" encoding="UTF-8"?>
      <PERSON>
          <NAMETAG>NAME</NAMETAG>
          <DOBTAG>DOB</DOBTAG>
          <SCORE1TAG>SCORE1</SCORE1TAG>
          <SCORE2TAG>SCORE2</SCORE2TAG>
      </PERSON>

To this:对此:

      <?xml version="1.0" encoding="UTF-8"?>
      <PERSON>
          <NAMETAG>John Doe</NAMETAG>
          <DOBTAG>01/01/2020</DOBTAG>
          <SCORE1TAG>90.5</SCORE1TAG>
          <SCORE2TAG>100.0</SCORE2TAG>
      </PERSON>

I would prefer to not use search and replace but instead navigate the WordprocessingDocument to find the correct properties to modify.我宁愿不使用搜索和替换,而是导航 WordprocessingDocument 以找到要修改的正确属性。 I tried to do a whole delete/add but that corrupted the file and did not work.我试图做一个完整的删除/添加,但破坏了文件并且没有工作。 Here is that code:这是该代码:

static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            byte[] byteArray = File.ReadAllBytes(@"C:\Simple_Template.docx");

            using (MemoryStream stream = new MemoryStream())
            {
                stream.Write(byteArray, 0, (int)byteArray.Length);
                WordprocessingDocument doc = WordprocessingDocument.Open(stream, true);

                doc.MainDocumentPart.DeleteParts<CustomXmlPart>(doc.MainDocumentPart.CustomXmlParts);

                string newcustomXML = @"<?xml version=""1.0\"" encoding=""UTF-8\""?><Person><NAMETAG>John Doe</NAMETAG><DOBTAG>DOB</DOBTAG><SCORE1TAG>90.5</SCORE1TAG><SCORE2TAG>100.0</SCORE2TAG></PERSON>";

                CustomXmlPart xmlPart = doc.MainDocumentPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
                byte[] byteArrayXML = Encoding.UTF8.GetBytes(newcustomXML);
                using (MemoryStream xml_strm = new MemoryStream(byteArrayXML))
                {
                    xmlPart.FeedData(xml_strm);
                }


                doc.MainDocumentPart.Document.Save();
                doc.Close();

                File.WriteAllBytes(@"C:\Simple_Template_Replace.docx", stream.ToArray());
            }
        }

I have also tried to navigate through the structure but I am having a hard time figuring out where in the WordprocessingDocument object contains the actual values that I need to modify.我也尝试浏览该结构,但我很难弄清楚 WordprocessingDocument object 中的哪个位置包含我需要修改的实际值。 Ideally, I would like something like this psuedo-code:理想情况下,我想要这样的伪代码:

doc.MainDocumentPart.CustomXMLPart.Select("NAMETAG") = "John Doe"

--------Follow On---------- --------关注---------

The answer below worked well without a Namespace.下面的答案在没有命名空间的情况下运行良好。 Now I would like to add one.现在我想添加一个。 This is the new XML:这是新的 XML:

<?xml version="1.0"?><myxml xmlns="www.mydomain.com">
<PERSON>
  <NAMETAG>NAME</NAMETAG>
  <DOBTAG>DOB</DOBTAG>
  <SCORE1TAG>SCORE1</SCORE1TAG>
  <SCORE2TAG>SCORE2</SCORE2TAG>
</PERSON>
</myxml>

I have adjusted the code to the following but the SelectSingleNode call is returning NULL.我已将代码调整为以下,但 SelectSingleNode 调用返回 NULL。 Here is the updated code:这是更新的代码:

                    XmlNamespaceManager mgr = new XmlNamespaceManager(xmlDocument.NameTable);
                    mgr.AddNamespace("ns", "www.mydomain.com");

                    string name_tag = xmlDocument.SelectSingleNode("/ns:myxml/ns:PERSON/ns:NAMETAG", mgr).InnerText;

I was able to fix this myself.我能够自己解决这个问题。 I did not realize that you need to include "ns:" with every element.我没有意识到您需要在每个元素中包含“ns:”。 I still thought that I would be able to pass in String.Empty into my AddNamespace and then I would not have to do it.我仍然认为我可以将 String.Empty 传递到我的 AddNamespace 中,然后我就不必这样做了。 But this will work for now.但这暂时可行。

The problem is with the newcustomXML value, it has two '\' characters in the XML declaration and also the start tag of "PERSON" element has capital case instead of upper case.问题在于newcustomXML值,它在 XML 声明中有两个 '\' 字符,并且“PERSON”元素的开始标记具有大写而不是大写。

So, try using the following instead:因此,请尝试使用以下内容:

string newcustomXML = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<PERSON>
    <NAMETAG>John Doe</NAMETAG>
    <DOBTAG>01/01/2020</DOBTAG>
    <SCORE1TAG>90.5</SCORE1TAG>
    <SCORE2TAG>100.0</SCORE2TAG>
</PERSON>";

Also regarding your navigation attempt, try using this:另外关于您的导航尝试,请尝试使用:

static void Main(string[] args)
{
    Console.WriteLine("Hello World!");

    byte[] byteArray = File.ReadAllBytes(@"C:\Simple_Template.docx");
    using (MemoryStream stream = new MemoryStream())
    {
        stream.Write(byteArray, 0, (int)byteArray.Length);
        WordprocessingDocument doc = WordprocessingDocument.Open(stream, true);

        CustomXmlPart xmlPart = doc.MainDocumentPart.CustomXmlParts.First();
        XmlDocument xmlDocument = new XmlDocument();

        using (var inputStream = xmlPart.GetStream(FileMode.Open, FileAccess.Read))
        using (var outputStream = new MemoryStream())
        {
            xmlDocument.Load(inputStream);
            xmlDocument.SelectSingleNode("/PERSON/NAMETAG").InnerText = "John Doe";

            xmlDocument.Save(outputStream);
            outputStream.Seek(0, SeekOrigin.Begin);
            xmlPart.FeedData(outputStream);
        }

        doc.MainDocumentPart.Document.Save();
        doc.Close();

        File.WriteAllBytes(@"C:\Simple_Template_Replace.docx", stream.ToArray());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM