在 C# 中操作 Word 2007 文档 XML
我正在尝试用 C# 操作 Word 2007 文档的 XML。我已经设法找到并操作我想要的节点,但现在我似乎不知道如何将其保存回来。这是我正在尝试的:
// Open the document from memoryStream
Package pkgFile = Package.Open(memoryStream, FileMode.Open, FileAccess.ReadWrite);
PackageRelationshipCollection pkgrcOfficeDocument = pkgFile.GetRelationshipsByType(strRelRoot);
foreach (PackageRelationship pkgr in pkgrcOfficeDocument)
{
if (pkgr.SourceUri.OriginalString == "/")
{
Uri uriData = new Uri("/word/document.xml", UriKind.Relative);
PackagePart pkgprtData = pkgFile.GetPart(uriData);
XmlDocument doc = new XmlDocument();
doc.Load(pkgprtData.GetStream());
NameTable nt = new NameTable();
XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
nsManager.AddNamespace("w", nsUri);
XmlNodeList nodes = doc.SelectNodes("//w:body/w:p/w:r/w:t", nsManager);
foreach (XmlNode node in nodes)
{
if (node.InnerText == "{{TextToChange}}")
{
node.InnerText = "success";
}
}
if (pkgFile.PartExists(uriData))
{
// Delete template "/customXML/item1.xml" part
pkgFile.DeletePart(uriData);
}
PackagePart newPkgprtData = pkgFile.CreatePart(uriData, "application/xml");
StreamWriter partWrtr = new StreamWriter(newPkgprtData.GetStream(FileMode.Create, FileAccess.Write));
doc.Save(partWrtr);
partWrtr.Close();
}
}
pkgFile.Close();
我收到错误“内存流不可扩展”。有什么想法吗?
I am trying to manipulate the XML of a Word 2007 document in C#. I have managed to find and manipulate the node that I want but now I can't seem to figure out how to save it back. Here is what I am trying:
// Open the document from memoryStream
Package pkgFile = Package.Open(memoryStream, FileMode.Open, FileAccess.ReadWrite);
PackageRelationshipCollection pkgrcOfficeDocument = pkgFile.GetRelationshipsByType(strRelRoot);
foreach (PackageRelationship pkgr in pkgrcOfficeDocument)
{
if (pkgr.SourceUri.OriginalString == "/")
{
Uri uriData = new Uri("/word/document.xml", UriKind.Relative);
PackagePart pkgprtData = pkgFile.GetPart(uriData);
XmlDocument doc = new XmlDocument();
doc.Load(pkgprtData.GetStream());
NameTable nt = new NameTable();
XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
nsManager.AddNamespace("w", nsUri);
XmlNodeList nodes = doc.SelectNodes("//w:body/w:p/w:r/w:t", nsManager);
foreach (XmlNode node in nodes)
{
if (node.InnerText == "{{TextToChange}}")
{
node.InnerText = "success";
}
}
if (pkgFile.PartExists(uriData))
{
// Delete template "/customXML/item1.xml" part
pkgFile.DeletePart(uriData);
}
PackagePart newPkgprtData = pkgFile.CreatePart(uriData, "application/xml");
StreamWriter partWrtr = new StreamWriter(newPkgprtData.GetStream(FileMode.Create, FileAccess.Write));
doc.Save(partWrtr);
partWrtr.Close();
}
}
pkgFile.Close();
I get the error 'Memory stream is not expandable'. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我建议您使用 Open XML SDK 而不是黑客攻击格式自己定。
I would recommend that you use Open XML SDK instead of hacking the format by yourself.
使用 OpenXML SDK 2.0,我这样做:
您可以从中编写一个 GetPartAsXmlDocument,用它执行您想要的操作,然后使用 SavePart(part, xmlString) 将其流式传输回来。
希望这有帮助!
Using OpenXML SDK 2.0, I do this:
From this you could write a GetPartAsXmlDocument, do what you want with it, and then stream it back with SavePart(part, xmlString).
Hope this helps!
您应该使用 OpenXML SDK 来处理 docx 文件,而不是编写自己的包装器。
You should use the OpenXML SDK to work on docx files and not write your own wrapper.
问题似乎是 doc.Save(partWrtr) ,它是使用 newPkgprtData 构建的,而 newPkgprtData 是使用 pkgFile 构建的,它从内存流加载...因为您从内存流加载,所以它试图将文档保存回相同的位置内存流。这会导致您看到的错误。
不要将其保存到内存流,而是尝试将其保存到新文件或新内存流。
The problem appears to be doc.Save(partWrtr), which is built using newPkgprtData, which is built using pkgFile, which loads from a memory stream... Because you loaded from a memory stream it's trying to save the document back to that same memory stream. This leads to the error you are seeing.
Instead of saving it to the memory stream try saving it to a new file or to a new memory stream.
对于“内存流不可扩展”问题的简短回答是:
不要从内存流中打开文档。
因此,在这方面,早期的答案是正确的,只需打开一个文件即可。
从 MemoryStream 打开编辑文档(根据我的经验)很容易导致“内存流不可扩展”。
我想当进行需要扩展内存流的编辑时会出现该消息。
我发现我可以做一些编辑,但不能做任何增加尺寸的事情。
因此,f.ex 删除自定义 xml 部分是可以的,但添加一个和一些数据则不行。
因此,如果您确实需要打开内存流,则必须弄清楚如何打开可扩展的 MemoryStream(如果您想向其中添加内容)。
我有这个需求,希望能找到解决方案。
Stein-Tore Erdal
PS:刚刚注意到“2011 年 1 月 26 日 15:18”的答案。
不要认为这就是所有情况的答案。
我在尝试此操作时收到错误:
The short and simple answer to the issue with getting 'Memory stream is not expandable' is:
Do not open the document from memoryStream.
So in that respect the earlier answer is correct, simply open a file instead.
Opening from MemoryStream editing the document (in my experience) easy lead to 'Memory stream is not expandable'.
I suppose the message appears when one do edits that requires the memory stream to expand.
I have found that I can do some edits but not anything that add to the size.
So, f.ex deleting a custom xml part is ok but adding one and some data is not.
So if you actually need to open a memory stream you must figure out how to open an expandable MemoryStream if you want to add to it.
I have a need for this and hope to find a solution.
Stein-Tore Erdal
PS: just noticed the answer from "Jan 26 '11 at 15:18".
Don't think that is the answer in all situations.
I get the error when trying this: