如何使用OpenXML Sdk替换Paragraph的文本

时间:2010-11-25 10:35:24

标签: c# .net openxml openxml-sdk

我正在使用.Net OpenXml SDK 2.0解析一些Openxml word文档。作为处理的一部分,我需要用其他句子替换某些句子。在迭代段落时,我知道当我找到需要替换的东西时,但我很难过如何替换它。

例如,假设我需要将带有html代码段的句子"a contract exclusively for construction work that is not building work."替换为下面的Sharepoint可重用内容。

<span class="ms-rtestate-read ms-reusableTextView" contentEditable="false" id="__publishingReusableFragment" fragmentid="/Sites/Sandbox/ReusableContent/132_.000" >a contract exclusively for construction work that is not building work.</span>

PS:我使用xslt得到了docx到Html的转换,所以在这个阶段这不是问题

Paragraph节点的InnerText属性为我提供了正确的文本,但内部文本属性本身不可设置。所以     Regex.Match(currentParagraph.InnerText, currentString).Success 返回true并告诉我当前段落包含我想要的文本。

正如我所说,InnerText本身不可设置,所以我尝试使用outerxml创建一个新段落,如下所示。

string modifiedOuterxml = Regex.Replace(currentParagraph.OuterXml, currentString, reusableContentString);
OpenXmlElement parent = currentParagraph.Parent;
Paragraph modifiedParagraph = new Paragraph(modifiedOuterxml);
parent.ReplaceChild<Paragraph>(modifiedParagraph, currentParagraph);

即使我不太关心这个级别的格式化并且似乎没有任何格式,但outerXML似乎有额外的元素可以打败正则表达式。

..."16" /><w:lang w:val="en-AU" /></w:rPr><w:t>a</w:t></w:r><w:proofErr w:type="gramEnd" /> <w:r w:rsidRPr="00C73B58"><w:rPr><w:sz w:val="16" /><w:szCs w:val="16" /><w:lang w:val="en-AU" /></w:rPr><w:t xml:space="preserve"> contract exclusively for construction work that is not building work.</w:t></w:r></w:p>

总而言之,我如何用其他文本替换OpenXml段落中的文本。即使以失去一些格式为代价。

2 个答案:

答案 0 :(得分:9)

我自己修好了。关键是要删除所有的运行并在当前段落中创建新的运行

string modifiedString = Regex.Replace(currentParagraph.InnerText, currentString, reusableContentString);
currentParagraph.RemoveAllChildren<Run>();
currentParagraph.AppendChild<Run>(new Run(new Text(modifiedString)));

答案 1 :(得分:0)

所有段落的内部都有一个text元素,因此您只需要查找该text元素并更新其文本即可,例如:

var text = part.RootElement.Descendants<Text>().FirstOrDefault(e=>e.Text == "a contract exclusively for construction work that is not building work.");
if(text != null)
{
    text.Text = "New text here";
}
mainPart.Document.Save();