C# OpenXML:Replace<;sdt/>;WordprocessingML中带表的元素

C# OpenXML:Replace<;sdt/>;WordprocessingML中带表的元素,c#,openxml-sdk,openxml,C#,Openxml Sdk,Openxml,我使用OpenXMLSDK以编程方式将一些元素替换为OpenXML(WordProcessingML)标记块 例如,我有一段内容如下: <w:p> <w:run><w:text> Text before </w:text></w:run> <w:sdt><w:sdtPr> ...</w:sdtPr><w:sdtContent>...</w:sdtContent><

我使用OpenXMLSDK以编程方式将一些
元素替换为OpenXML(WordProcessingML)标记块

例如,我有一段内容如下:

<w:p>
  <w:run><w:text> Text before </w:text></w:run>
  <w:sdt><w:sdtPr> ...</w:sdtPr><w:sdtContent>...</w:sdtContent></w:sdt>
  <w:run><w:text> Text after </w:text></w:run>
</w:p>

之前的文本
......
后文
还有一张结构如下的桌子:

<w:tbl>
  <w:tblPr>...</w:tblPr>
  <w:tblGrid> ... gridCol elements ...</w:tblGrid>
  <w:tr>
    <w:trPr>...</w:trPr>
    <w:tc>
   <w:tcPr>...</w:tcPr>
   <w:p> Cell contents </w:p>
    </w:tc>
    <w:tc>
   <w:tcPr>...</w:tcPr>
   <w:p> Cell contents </w:p>
    </w:tc>
  </w:tr>
 </w:tbl>

...
... 网格元素。。。
...
...
细胞内容物
...
细胞内容物
基本上,我想用表标记替换段落中的
元素。 问题是我不能仅仅替换它,因为它将创建一个无效的文档(在另一个段落元素中包含段落的表无效)

我想得到的结果是:

<w:p>
  <w:run><w:text> Text before </w:text></w:run>
</w:p>
<w:tbl>
  <w:tblPr>...</w:tblPr>
  <w:tblGrid> ... gridCol elements ...</w:tblGrid>
  <w:tr>
    <w:trPr>...</w:trPr>
    <w:tc>
   <w:tcPr>...</w:tcPr>
   <w:p> Cell contents </w:p>
    </w:tc>
    <w:tc>
   <w:tcPr>...</w:tcPr>
   <w:p> Cell contents </w:p>
    </w:tc>
  </w:tr>
</w:tbl>
<w:p>
  <w:run><w:text> Text after </w:text></w:run>
</w:p>

之前的文本
...
... 网格元素。。。
...
...
细胞内容物
...
细胞内容物
后文
我在考虑创建一个方法,创建一个新段落,其中包含
元素之前的元素,另一个段落包含sdt元素之后的元素,但这种方法似乎很容易出错

有没有一种方法可以做我想做的事情而不需要手动操作(当我尝试在文本行中插入一个新表时,一种方法可以做Word所做的事情)


任何帮助都将不胜感激。

我完全认为您应该将要替换为表的内容控件前后的运行拆分为单独的段落。但只有当你给Word一个理由让它进行奇怪的运行时,它才是真正容易出错的。就像我想要的一样,一个新事物将是三次运行,因为在这句话中Wastes在语法上是不正确的,Word会将其标记为dirty,除非/直到您在Word中选择更正它或忽略它,否则它将保持三次运行。这是我唯一能预见的问题

然而,如果你有一个策略(比如强制用户检查他们的文档的拼写),剩下的当然是可行的。如果您不熟悉Eric White的博客,那么在Word中使用OpenXMLSDK开发时,它将是您最好的朋友。例如,仅这些文章就应该回答您关于如何使用函数转换来解析、插入和替换的大部分/所有问题


  • 谢谢你的回答,我不确定我说的是否清楚,我只是用预期的行为更新了问题。另一件需要考虑的事情是,原始段落中可能有嵌套的内容(如段落中的sdt元素),在拆分现有段落并创建新段落时,我必须考虑到这一点。@willvv:是的,你第一次这么做是很清楚的。建议仍然有效-您可能会通过Linq在每个段落上搜索,定位任何第一级
    元素,在这之前进行所有运行,从中创建一个段落元素,与之后的所有段落元素相同,然后使用
    将其替换为
    。或者,您可以对其中的信息进行更多的处理、更改,并根据需要使用这些信息。当您拥有所有这些内容时,您只需重写以替换原始的

    。上面的链接将帮助您完成这项任务。我只是想与您联系,看看您是否有机会查看下面的链接和解决方案。嗨@Otaku谢谢您的回答,是的,最后我就是这么做的,基本上,我为sdt之后的元素和sdt之前的元素手动创建了段落。很高兴听到它为您解决了问题。@willvv能否请您提供一些用于执行任务的代码(如果不是秘密的话)?:)@JanisVeinbergs我很抱歉,我在以前的工作中做过这件事,我再也无法访问代码了。