使用 OpenXML C# 编辑 CustomXML
Edit CustomXML with OpenXML C#
这是我的第一个 OpenXML 项目。我正在尝试编辑 docx 文件的 CustomXML 文件。我正在尝试改变这一点:
<?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 以找到要修改的正确属性。我试图做一个完整的 delete/add 但这损坏了文件并且没有工作。这是代码:
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 对象中的哪个位置包含我需要修改的实际值。理想情况下,我想要这样的伪代码:
doc.MainDocumentPart.CustomXMLPart.Select("NAMETAG") = "John Doe"
--------关注---------
下面的答案在没有命名空间的情况下也很有效。现在我想补充一个。这是新的 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。这是更新后的代码:
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 中,然后我就不必这样做了。但这暂时有效。
问题出在 newcustomXML
值上,它在 XML 声明中有两个 '\' 字符,而且“PERSON”元素的开始标记是大写字母而不是大写字母。
所以,请尝试使用以下方法:
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>";
关于您的导航尝试,请尝试使用此:
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 项目。我正在尝试编辑 docx 文件的 CustomXML 文件。我正在尝试改变这一点:
<?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 以找到要修改的正确属性。我试图做一个完整的 delete/add 但这损坏了文件并且没有工作。这是代码:
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 对象中的哪个位置包含我需要修改的实际值。理想情况下,我想要这样的伪代码:
doc.MainDocumentPart.CustomXMLPart.Select("NAMETAG") = "John Doe"
--------关注---------
下面的答案在没有命名空间的情况下也很有效。现在我想补充一个。这是新的 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。这是更新后的代码:
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 中,然后我就不必这样做了。但这暂时有效。
问题出在 newcustomXML
值上,它在 XML 声明中有两个 '\' 字符,而且“PERSON”元素的开始标记是大写字母而不是大写字母。
所以,请尝试使用以下方法:
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>";
关于您的导航尝试,请尝试使用此:
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());
}
}