在 Word 文档中找不到段落和 table(打开 XML)
Paragraphs and table not found in a Word Document (open XML)
我使用 MS Word 创建了简单的打开 XML 文档 (.dotx)。该文件包含简单文本和一个 table。我试图用新文本替换文本中的几个自定义占位符,但是下面的代码片段在文档中找不到任何 Paragraph
或 Table
。我已经尝试创建几个新的 .dotx 文件,还尝试了文档类型的不同变体,即使用 MS Word .dotx
和 (Strict Open XML) .docx
,但问题仍然存在。
using (WordprocessingDocument doc =
WordprocessingDocument.Open(templatePath, true))
{
var body = doc.MainDocumentPart.Document.Body;
var paras = body.Elements<Paragraph>(); // <-- always empty
var tables = body.Descendants<Table>(); // <-- always empty
foreach (Table t in tables)
{
t.Append(new TableRow(new TableCell(new Paragraph(new Run(new Text("test"))))));
}
foreach (var para in paras)
{
foreach (var run in para.Elements<Run>())
{
foreach (var text in run.Elements<Text>())
{
if (text.Text.Contains("###name###"))
{
text.Text = text.Text.Replace("###name###", "Sample");
}
}
}
}
doc.SaveAs(resultPath);
}
有趣的是,如果我使用 MS 文档中的以下代码片段,它确实有效,但是不清楚如何向 table 添加额外的行。因此,我宁愿使用第一种方法。知道文件或上面的代码可能有什么问题吗?
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(templatePath, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
Regex regexText = new Regex("###name###");
docText = regexText.Replace(docText, "My Text!");
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
当您使用像 MS Word 这样的编辑器创建文档时,它可以添加一些容器来包装您的段落,我建议您检查 xml 生成的内容。为此,您只需将 .docx
重命名为 .zip
并打开该存档。
您需要使用任何文本编辑器打开 word/document.xml
并查看 <w:p>
是否是 <w:body>
的直接 child。如果不是直接的,使用descendants
方法。
var paras = body.Descendants<Paragraph>(); // <-- always empty
Elements
只查找直接 children.
Descendants
在任意级别找到 children。
此外,最常见的问题是命名空间错误,因为 Paragraph
存在于 OpenXml
的命名空间中,您必须使用 using DocumentFormat.OpenXml.Wordprocessing;
我使用 MS Word 创建了简单的打开 XML 文档 (.dotx)。该文件包含简单文本和一个 table。我试图用新文本替换文本中的几个自定义占位符,但是下面的代码片段在文档中找不到任何 Paragraph
或 Table
。我已经尝试创建几个新的 .dotx 文件,还尝试了文档类型的不同变体,即使用 MS Word .dotx
和 (Strict Open XML) .docx
,但问题仍然存在。
using (WordprocessingDocument doc =
WordprocessingDocument.Open(templatePath, true))
{
var body = doc.MainDocumentPart.Document.Body;
var paras = body.Elements<Paragraph>(); // <-- always empty
var tables = body.Descendants<Table>(); // <-- always empty
foreach (Table t in tables)
{
t.Append(new TableRow(new TableCell(new Paragraph(new Run(new Text("test"))))));
}
foreach (var para in paras)
{
foreach (var run in para.Elements<Run>())
{
foreach (var text in run.Elements<Text>())
{
if (text.Text.Contains("###name###"))
{
text.Text = text.Text.Replace("###name###", "Sample");
}
}
}
}
doc.SaveAs(resultPath);
}
有趣的是,如果我使用 MS 文档中的以下代码片段,它确实有效,但是不清楚如何向 table 添加额外的行。因此,我宁愿使用第一种方法。知道文件或上面的代码可能有什么问题吗?
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(templatePath, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
Regex regexText = new Regex("###name###");
docText = regexText.Replace(docText, "My Text!");
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
当您使用像 MS Word 这样的编辑器创建文档时,它可以添加一些容器来包装您的段落,我建议您检查 xml 生成的内容。为此,您只需将 .docx
重命名为 .zip
并打开该存档。
您需要使用任何文本编辑器打开 word/document.xml
并查看 <w:p>
是否是 <w:body>
的直接 child。如果不是直接的,使用descendants
方法。
var paras = body.Descendants<Paragraph>(); // <-- always empty
Elements
只查找直接 children.
Descendants
在任意级别找到 children。
此外,最常见的问题是命名空间错误,因为 Paragraph
存在于 OpenXml
的命名空间中,您必须使用 using DocumentFormat.OpenXml.Wordprocessing;