【问题标题】:Descendants<T> gets zero elements in Word docDescendants<T> 在 Word doc 中获得零个元素
【发布时间】:2019-06-17 06:27:35
【问题描述】:

我在更新 Word 文档 (Q How to update the body and a hyperlink in a Word doc ) 中的超链接时遇到问题,并且正在放大 Descendants&lt;T&gt;() 调用不起作用。这是我的代码:

using DocumentFormat.OpenXml.Packaging;      //from NuGet ClosedXML
using DocumentFormat.OpenXml.Wordprocessing; //from NuGet ClosedXML

WordprocessingDocument doc = WordprocessingDocument.Open(...filename..., true);
MainDocumentPart mainPart = doc.MainDocumentPart;
IEnumerable<Hyperlink> hLinks = mainPart.Document.Body.Descendants<Hyperlink>();

文档可以正常打开,因为mainPart 获得了一个值。但是hLinks 没有元素。如果我在 Word 中打开 Word 文档,则会出现一个超链接并且可以正常工作。

在即时窗口中,我看到以下值:

mainPart.Document.Body
-->
{DocumentFormat.OpenXml.Wordprocessing.Body}
    ChildElements: {DocumentFormat.OpenXml.OpenXmlChildElements}
    ExtendedAttributes: {DocumentFormat.OpenXml.EmptyEnumerable<DocumentFormat.OpenXml.OpenXmlAttribute>}
    FirstChild: {DocumentFormat.OpenXml.OpenXmlUnknownElement}
    HasAttributes: false
    HasChildren: true
    InnerText: "
       lots of data, e.g:
    ...<w:t>100</w:t>...

mainPart.Document.Body.Descendants<Text>().First()
-->
Exception: "Sequence contains no elements"

如果我什至找不到文本部分,我应该如何找到和替换超链接?

【问题讨论】:

  • 嗯,问题中的代码对我有用 - 我复制并粘贴了该行。
  • @CindyMeister 我在问题中添加了更多测试输出。它显示为 FirstChild 和 OpenXmlUnknownElement,这有什么要担心的吗?这和你做的测试有什么不同吗?

标签: c# openxml-sdk wordml


【解决方案1】:

如果您确定文件中有您正在使用 linq 搜索的元素,但没有返回任何内容或您遇到异常,这通常表明存在命名空间问题。

如果您发布整个文件,我可以更好地帮助您,但请检查您是否可以像这样为您的命名空间设置别名:

using W = DocumentFormat.OpenXml.Wordprocessing;

然后在您的Descendants 电话中执行以下操作:

var hLinks = mainPart.Document.Body.Descendants<W.Hyperlink>();

这个answer 演示了另一个可以尝试的命名空间技巧。

【讨论】:

  • 很棒的命名空间技巧,但这不是解决方案。将鼠标悬停在超链接或后代上,将显示命名空间。此外,使用 VisualStudio 中的 Goto Definition 功能,可以找到正确的库。添加两行源代码后,第二行中的 W 显示为灰色,这意味着它是多余的,并且导致与没有 W. 前缀的命名空间相同。所以我会赞成但不接受你的回答。
  • 好的——如果你能发布一个最小的解决方案和数据文件,我们可以重现它,我相信我们可以解决它并找出问题的根源。通常,您会在开发最小解决方案时找到解决方案。请看:stackoverflow.com/help/mcve
【解决方案2】:

我的 Word 文档似乎有问题;它是用工具生成的。使用 Word 创建的另一个 Word 文档进行测试会产生更好的结果。我正在努力...

使用常规 Word 文档,查看

doc.MainDocumentPart.Document.Body.InnerXml

值以:

开头
<w:p w:rsidR=\"00455325\" w:rsidRDefault=\"00341915\" 
  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">
  <w:r>
    <w:t>Hello World!

但我正在测试的单词是 doc,它来自我自己制作的工具:

<w:body xmlns:w=\"http://schemas.openxmlforma...

这解释了很多。 我将不得不修复我的工具:-)


更新:

解决方法是,这没有提供要插入 Word Doc 的正确数据部分:

string strDocumentXml = newWordContent.DocumentElement.InnerXml;

但这是正确的数据:

string strDocumentXml = newWordContent.DocumentElement.FirstChild.OuterXml;

用调试器检查:

doc.MainDocumentPart.Document.Body.InnerXml

如上所述,确认它。 Descendants 调用现在返回预期的数据,并且可以更新超链接。


旁注:

我清楚地修复了我的应用程序中的一个错误,但是,除了更新超链接之外,该应用程序之前运行得非常好,有那个错误:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    相关资源
    最近更新 更多