Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 45 additions & 6 deletions OpenXmlFormats/Wordprocessing/Markup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,49 @@ public class CT_Comments

private List<CT_Comment> commentField;

private Dictionary<string, string> extraXmlNamespace = new Dictionary<string, string>();
private Dictionary<string, string> defaultXmlNamespace = new Dictionary<string, string>(){
{ "o", "urn:schemas-microsoft-com:office:office" },
{ "ve", "http://schemas.openxmlformats.org/markup-compatibility/2006" },
{ "r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships" },
{ "v", "urn:schemas-microsoft-com:vml" },
{ "m", "http://schemas.openxmlformats.org/officeDocument/2006/math" },
{ "w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main" },
{ "wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" },
{ "w10", "urn:schemas-microsoft-com:office:word" },
{ "w14", "http://schemas.microsoft.com/office/word/2010/wordml" },
{ "wne", "http://schemas.microsoft.com/office/word/2006/wordml" },

};
public CT_Comments()
{
this.commentField = new List<CT_Comment>();
}
private void FindExtraNamespace(XmlNode node)
{
if (node.Attributes != null)
{
foreach (XmlAttribute attr in node.Attributes)
{
if (attr.Name.StartsWith("xmlns:"))
{
string[] strs = attr.Name.Split(':');
if (strs.Length == 2)
{
if (!extraXmlNamespace.ContainsKey(strs[1]) &&
!defaultXmlNamespace.ContainsKey(strs[1]))
extraXmlNamespace.Add(strs[1], attr.Value);
}
}
}
}
}
public static CT_Comments Parse(XmlNode node, XmlNamespaceManager namespaceManager)
{
if (node == null)
return null;
CT_Comments ctObj = new CT_Comments();
ctObj.FindExtraNamespace(node);
ctObj.comment = new List<CT_Comment>();
foreach (XmlNode childNode in node.ChildNodes)
{
Expand All @@ -201,16 +235,21 @@ public static CT_Comments Parse(XmlNode node, XmlNamespaceManager namespaceManag
}



private void WriteXmlNamespace(StreamWriter sw, Dictionary<string, string> ns)
{
if(ns == null || ns.Count == 0)
return;
foreach (var kv in ns)
{
sw.Write(string.Format($"xmlns:{kv.Key}=\"{kv.Value}\" ", kv.Key, kv.Value));
}
}
internal void Write(StreamWriter sw)
{
sw.Write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
sw.Write(string.Format("<w:comments "));
sw.Write("xmlns:ve=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" ");
sw.Write("xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" ");
sw.Write("xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" ");
sw.Write("xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" ");
sw.Write("xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\">");
WriteXmlNamespace(sw, defaultXmlNamespace);
WriteXmlNamespace(sw, extraXmlNamespace);
sw.Write(">");
if (this.comment != null)
{
Expand Down
28 changes: 28 additions & 0 deletions testcases/ooxml/XWPF/UserModel/TestXWPFComments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using NPOI.XWPF.UserModel;
using NUnit.Framework;
using System.Collections.Generic;
using System.IO;
using System.Reflection.Metadata;

[TestFixture]
public class TestXWPFComments
Expand Down Expand Up @@ -56,5 +58,31 @@ public void TestReadComments()
Assert.AreEqual(1, allPictures.Count);
}
}

[Test]
public void TestNPOIBug1481()
{
using(XWPFDocument doc = XWPFTestDataSamples.OpenSampleDocument("NPOI-bug-1481.docx"))
{
XWPFComment[] comments = doc.GetComments();
Assert.AreEqual(1, comments.Length);

XWPFComment comment = comments[0];
Assert.AreEqual("Claudio Pais", comment.GetAuthor());
Assert.AreEqual("2025-01-23T17:18:00Z", comment.Date);
Assert.AreEqual("Bla bla", comment.GetText());

XWPFDocument docIn = XWPFTestDataSamples.WriteOutAndReadBack(doc);

comments = docIn.GetComments();
Assert.AreEqual(1, comments.Length);

comment = comments[0];
Assert.AreEqual("Claudio Pais", comment.GetAuthor());
Assert.AreEqual("2025-01-23T17:18:00Z", comment.Date);
Assert.AreEqual("Bla bla", comment.GetText());

}
}
}
}
Binary file added testcases/test-data/document/NPOI-bug-1481.docx
Binary file not shown.