C#.NET检索由特定注释引用的文本的列表号

问题描述 投票:0回答:1

我正在尝试检索由特定注释引用的一段文本的列表号,如此处所示的示例。在此示例中,应检索3.3.1.1.1.-I。这是一个自定义列表样式。enter image description here

我将如何去做?

已经使用OpenXML SDK完成了以下操作。

public static void GetCommentsFromDocument(string fileName)
        {

            int pageCount = 0;
            Dictionary<int, string> sectionDict = new Dictionary<int, string>(); // ID linking section and comment, section text
            Dictionary<int, string> commentDict = new Dictionary<int, string>(); // ID linking section and comment, comment text

            using (var wordDoc = WordprocessingDocument.Open(fileName, false))
            {

                MainDocumentPart mainPart = wordDoc.MainDocumentPart;
                var document = mainPart.Document;
                var commentsPart = mainPart.WordprocessingCommentsPart;


                //var comments = commentsPart.Comments;


                //foreach (Comment comment in comments)
                foreach (Comment comment in commentsPart.Comments.Elements<Comment>())
                {
                    string commentId = comment.Id;
                    string commentText = comment.InnerText;

                    // Console.WriteLine("ID: {0}  | Txt: {1}", commentId, commentText);

                    OpenXmlElement rangeStart = document.Descendants<CommentRangeStart>().Where(c => c.Id == commentId).FirstOrDefault();
                    List<OpenXmlElement> referenced = new List<OpenXmlElement>();

                    if (rangeStart==null)
                    {
                        continue;
                    }

                    // rangeStart = rangeStart.NextSibling(); //Whats the point of this?

                    while (!(rangeStart is CommentRangeEnd))
                    {
                        // Console.WriteLine("C_ID: {0} | Comment: {1} | SectionText: {2}", commentId, commentText, rangeStart.InnerText);
                        //section.Add();
                        if (!commentDict.ContainsKey(Convert.ToInt32(commentId)))
                        {
                            commentDict.Add(Convert.ToInt32(commentId), commentText);
                            sectionDict.Add(Convert.ToInt32(commentId), rangeStart.InnerText);
                        }
                        else
                        {
                            commentDict[Convert.ToInt32(commentId)] += commentText;
                            sectionDict[Convert.ToInt32(commentId)] += rangeStart.InnerText;
                        }



                        rangeStart = rangeStart.NextSibling();
                    }


                    foreach(var com in commentDict)
                    {
                        int comId = com.Key;
                        string commText = com.Value;
                        string sectionText = sectionDict[comId];
                        Console.WriteLine("C_ID: {0} | Comment: {1} | SectionText: {2}", comId, commText, sectionText);
                    }

                }
                Console.WriteLine("finished");

                Console.ReadKey();
            }
        }

总而言之,以上代码将返回类似:

C_ID: 1 | Comment: Test comment | SectionText: 

编辑:使用OpenXML电动工具库中的RetrieveListItem方法是否可行?它具有以下参数:

RetrieveListItem(WordprocessingDocument wordDoc, XElement paragraph)
c# .net ms-word openxml docx
1个回答
0
投票

简短的答案是“是”。

这里是显示如何使用ListItemRetriever.RetrieveListItem()方法的单元测试。

using System.Linq;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;
using OpenXmlPowerTools;
using Xunit;
using Xunit.Abstractions;

namespace CodeSnippets.Tests.OpenXml.Wordprocessing
{
    public class ListItemRetrieverTests
    {
        private readonly ITestOutputHelper _output;

        public ListItemRetrieverTests(ITestOutputHelper output)
        {
            _output = output;
        }

        [Fact]
        public void RetrieveListItem_DocumentWithNumberedLists_ListItemSuccessfullyRetrieved()
        {
            const string path = "Resources\\Numbered Lists.docx";
            using WordprocessingDocument wordDoc = WordprocessingDocument.Open(path, false);

            XElement document = wordDoc.MainDocumentPart.GetXElement();

            foreach (XElement paragraph in document.Descendants(W.p))
            {
                string listItem = ListItemRetriever.RetrieveListItem(wordDoc, paragraph);
                string text = paragraph.Descendants(W.t).Select(t => t.Value).StringConcatenate();

                _output.WriteLine(string.IsNullOrEmpty(listItem) ? text : $"{listItem} {text}");
            }
        }
    }
}

假设您正在以下w:document元素上使用它:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid wp14">
  <w:body>
    <w:p w14:paraId="340B6503" w14:textId="43A80410" w:rsidR="006E0597" w:rsidRDefault="006E0597" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="Title"/>
      </w:pPr>
      <w:r>
        <w:t>Title</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="1FB0B574" w14:textId="28D8DF5C" w:rsidR="006E0597" w:rsidRDefault="00605101" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="BodyText"/>
      </w:pPr>
      <w:r>
        <w:t>First Body Text</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="54B73789" w14:textId="64131A80" w:rsidR="006E0597" w:rsidRDefault="006E0597" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="ListLowerLetter0"/>
      </w:pPr>
      <w:r>
        <w:t>First letter</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="4BEC7C70" w14:textId="152CBBA5" w:rsidR="006E0597" w:rsidRDefault="006E0597" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="ListLowerLetter0"/>
      </w:pPr>
      <w:r>
        <w:t>Second letter</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="702765A1" w14:textId="1B34BB79" w:rsidR="006E0597" w:rsidRDefault="00605101" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="BodyText"/>
      </w:pPr>
      <w:r>
        <w:t>Second Body Text</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="39040551" w14:textId="6603DC8A" w:rsidR="006E0597" w:rsidRDefault="006E0597" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="ListDecimal0"/>
      </w:pPr>
      <w:r>
        <w:t>First decimal</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="3D308E46" w14:textId="1D79AE88" w:rsidR="006E0597" w:rsidRPr="006E0597" w:rsidRDefault="006E0597" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="ListDecimal0"/>
      </w:pPr>
      <w:r>
        <w:t>Second decimal</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="5CB3EB4E" w14:textId="55D0BD9D" w:rsidR="00F67B49" w:rsidRDefault="006E0597" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="Heading1"/>
      </w:pPr>
      <w:r>
        <w:t>First Heading 1</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="3F02258A" w14:textId="0C540797" w:rsidR="006E0597" w:rsidRDefault="006E0597" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="Heading2"/>
      </w:pPr>
      <w:r>
        <w:t>First Heading 2</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="0EB3E93A" w14:textId="0F4E1DA5" w:rsidR="00605101" w:rsidRDefault="00605101" w:rsidP="00605101">
      <w:pPr>
        <w:pStyle w:val="HeadingBody2"/>
      </w:pPr>
      <w:r>
        <w:t>First Body</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="39BEE8F6" w14:textId="4764A259" w:rsidR="006E0597" w:rsidRDefault="006E0597" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="Heading2"/>
      </w:pPr>
      <w:r>
        <w:t>Second Heading 2</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="7AB4FC15" w14:textId="654D7F1E" w:rsidR="00605101" w:rsidRDefault="00605101" w:rsidP="00605101">
      <w:pPr>
        <w:pStyle w:val="HeadingBody2"/>
      </w:pPr>
      <w:r>
        <w:t>Second Body</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="2241BF2E" w14:textId="2E71E842" w:rsidR="006E0597" w:rsidRDefault="006E0597" w:rsidP="006E0597">
      <w:pPr>
        <w:pStyle w:val="Heading1"/>
      </w:pPr>
      <w:r>
        <w:t>Second Heading 1</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="59CED7B3" w14:textId="05393BB9" w:rsidR="00605101" w:rsidRDefault="00626475" w:rsidP="00605101">
      <w:pPr>
        <w:pStyle w:val="Heading2"/>
      </w:pPr>
      <w:r>
        <w:t>Third Heading 2</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="4E4E6311" w14:textId="68933A55" w:rsidR="00605101" w:rsidRDefault="00605101" w:rsidP="00605101">
      <w:pPr>
        <w:pStyle w:val="Heading3"/>
      </w:pPr>
      <w:r>
        <w:t>First Heading 3</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="17187080" w14:textId="67E4474C" w:rsidR="00605101" w:rsidRDefault="00605101" w:rsidP="00605101">
      <w:pPr>
        <w:pStyle w:val="Heading3"/>
      </w:pPr>
      <w:r>
        <w:t>Second Heading 3</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="6DF37BE4" w14:textId="2DDE26DD" w:rsidR="00605101" w:rsidRDefault="00605101" w:rsidP="00605101">
      <w:pPr>
        <w:pStyle w:val="Heading4"/>
      </w:pPr>
      <w:r>
        <w:t>First Heading 4</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="330159A6" w14:textId="5EACA3DB" w:rsidR="00605101" w:rsidRDefault="00605101" w:rsidP="00605101">
      <w:pPr>
        <w:pStyle w:val="HeadingBody3"/>
      </w:pPr>
      <w:r>
        <w:t>Third Body</w:t>
      </w:r>
    </w:p>
    <w:p w14:paraId="2D22AA65" w14:textId="23674F82" w:rsidR="00605101" w:rsidRDefault="00605101" w:rsidP="00605101">
      <w:pPr>
        <w:pStyle w:val="Heading4"/>
      </w:pPr>
      <w:r>
        <w:t>Second Heading 4</w:t>
      </w:r>
      <w:bookmarkStart w:id="0" w:name="_GoBack"/>
      <w:bookmarkEnd w:id="0"/>
    </w:p>
    <w:p w14:paraId="4D61E765" w14:textId="3980F06B" w:rsidR="00605101" w:rsidRPr="00605101" w:rsidRDefault="00605101" w:rsidP="00605101">
      <w:pPr>
        <w:pStyle w:val="HeadingBody4"/>
      </w:pPr>
      <w:r>
        <w:t>Fourth Body</w:t>
      </w:r>
    </w:p>
    <w:sectPr w:rsidR="00605101" w:rsidRPr="00605101" w:rsidSect="003D11F7">
      <w:pgSz w:w="11907" w:h="16839" w:code="9"/>
      <w:pgMar w:top="1361" w:right="1701" w:bottom="1701" w:left="1701" w:header="510" w:footer="340" w:gutter="0"/>
      <w:cols w:space="708"/>
      <w:docGrid w:linePitch="360"/>
    </w:sectPr>
  </w:body>
</w:document>

测试输出如下:

Title
First Body Text
(a) First letter
(b) Second letter
Second Body Text
(1) First decimal
(2) Second decimal
1 First Heading 1
1.1 First Heading 2
First Body
1.2 Second Heading 2
Second Body
2 Second Heading 1
2.1 Third Heading 2
2.1.1 First Heading 3
2.1.2 Second Heading 3
2.1.2.1 First Heading 4
Third Body
2.1.2.2 Second Heading 4
Fourth Body

源代码和测试文档可以在我的CodeSnippets GitHub存储库中找到。

© www.soinside.com 2019 - 2024. All rights reserved.