使用OpenXML C#编辑CustomXML [英] Edit CustomXML with OpenXML C#

查看:77
本文介绍了使用OpenXML C#编辑CustomXML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的第一个OpenXML项目.我正在尝试编辑docx文件的CustomXML文件.我正在尝试更改此内容:

This is my first OpenXML project. I am trying to edit the CustomXML file of a docx file. 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>

对此:

      <?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>

我宁愿不使用搜索和替换,而是导航WordprocessingDocument来查找要修改的正确属性.我试图进行整个删除/添加,但是损坏了文件,无法正常工作.这是代码:

I would prefer to not use search and replace but instead navigate the WordprocessingDocument to find the correct properties to modify. 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());
            }
        }

我也尝试过浏览结构,但是很难弄清楚WordprocessingDocument对象中的哪些位置包含需要修改的实际值.理想情况下,我想要这样的伪代码:

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. Ideally, I would like something like this psuedo-code:

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

--------继续关注----------

--------Follow On----------

下面的答案在没有命名空间的情况下效果很好.现在,我想添加一个.这是新的XML:

The answer below worked well without a Namespace. Now I would like to add one. This is the new 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>

我已将代码调整为以下代码,但SelectSingleNode调用返回NULL.这是更新的代码:

I have adjusted the code to the following but the SelectSingleNode call is returning 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;

我能够自己解决此问题.我没有意识到您需要添加"ns:"每个元素.我仍然认为我可以将String.Empty传递到我的AddNamespace中,然后就不必这样做了.但这暂时适用.

I was able to fix this myself. I did not realize that you need to include "ns:" with every element. 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. But this will work for now.

推荐答案

问题出在 newcustomXML 值上,它在XML声明中有两个'\'字符,并且还有'; PERSON";元素使用大写字母而不是大写字母.

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.

因此,请尝试使用以下内容:

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());
    }
}

这篇关于使用OpenXML C#编辑CustomXML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆