问题
I am having trouble updating a Hyperlink in a Word doc (Q How to update the body and a hyperlink in a Word doc ) and am zooming in on the Descendants<T>()
call not working. Here is my code:
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>();
The doc is opened OK because mainPart
gets a value. But hLinks
has no elements. If I open the Word doc in Word, a hyperlink is present and working.
In the Immediate Window I see the following values:
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"
If I cannot even find the text parts, how should I ever find and replace the hyperlink?
回答1:
If you are sure there are elements in your file that you are searching with linq, and nothing is returning or you are getting exceptions, that typically points to a namespace problem.
If you post your entire file, I can better help you, but check to see if you can alias your namespace like so:
using W = DocumentFormat.OpenXml.Wordprocessing;
and then in your Descendants
call you do something like this:
var hLinks = mainPart.Document.Body.Descendants<W.Hyperlink>();
This answer demonstrates another namespace trick to try also.
回答2:
Something seems to be wrong with my Word doc; it was generated with a tool. Testing with another Word doc, created with Word, gives better results. I am working on it ...
With a regular Word doc, looking at
doc.MainDocumentPart.Document.Body.InnerXml
the value starts with:
<w:p w:rsidR=\"00455325\" w:rsidRDefault=\"00341915\"
xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">
<w:r>
<w:t>Hello World!
but with the word doc I am testing with, which comes from a tool I myself made:
<w:body xmlns:w=\"http://schemas.openxmlforma...
This explains a lot. I will have to fix my tool :-)
Update:
The fix was that this did not give the correct part of data to insert in the Word Doc:
string strDocumentXml = newWordContent.DocumentElement.InnerXml;
but instead this is the correct data:
string strDocumentXml = newWordContent.DocumentElement.FirstChild.OuterXml;
Inspection with the debugger of:
doc.MainDocumentPart.Document.Body.InnerXml
as mentioned above, confirmed it. The Descendants call now returns the expected data, and updating the hyperlink works.
Side note:
I clearly fixed a bug in my app, but, apart from updating the hyperlink, the app worked perfectly OK before, with that bug :-)
来源:https://stackoverflow.com/questions/54331068/descendantst-gets-zero-elements-in-word-doc