0

我正在尝试解析一个冗长的文件并删除我不想要的部分。从研究看来,OpenXml SDK 是操作和搜索单词 doc 的最简单参考。不幸的是,它并不总是一致的,因为我NullReferenceExceptions在尝试将节点分配给运行对象时不断得到。本质上,我的程序应该遍历 docx 文件并找到标签 (ver 1),然后删除它和结束标签 (/ver 1) 之间的所有内容。这似乎只适用于某些部分,因为我得到了其他部分NullReferenceException,我觉得这与 MS Word 使用的凌乱格式有关,但我不知道。

如果有人可以帮助我欣赏它,这是特定部分的代码。

IEnumerable<OpenXmlElement> elem = main.Document.Body.Descendants().ToList();
foreach (OpenXmlElement elems in elem)
{
   if (elems is Text && elems.InnerText == s_Ver1)// s_Ver1 = "(Ver 1)"
   {
      Run run = (Run)elems.Parent;
      Paragraph p = (Paragraph)run.Parent;
      p.RemoveAllChildren();
      p.Remove();

      foreach (OpenXmlElement endelems in elem)
      {
         if (endelems is Text && elems.InnerText == e_Ver1)//e_Ver1 = "(/Ver1)"
         {
            run = (Run)endelems.Parent;
            p = (Paragraph)run.Parent;
            p.Remove();
            break;
         }

         else
         {
            Run d_Run = (Run)endelems.Parent;
            Paragraph d_p = (Paragraph)d_Run.Parent;
            d_p.RemoveAllChildren();
            d_p.Remove();*/

            try
            {
               endelems.Remove();
            }

            catch(Exception err)
            {
               MessageBox.Show(err.ToString());
            }
          }
       }
    }
}

编辑

尝试在代码中使用(在 endelems.remove() 周围)

 System.InvalidOperationException: The Parent of this element is Null
 //it also says line 141 but I'm not sure how to get line numbering in vs2010

尝试捕获整个事物的错误

 System.NullReferenceException: Object reference not set to an instance of an object
 //line 114 which would be Paragraph p = (Paragraph)run.Parent; line
4

1 回答 1

1

我不太确定你想在这里做什么,但是......

你从 body 中得到一个静态的子列表。

您迭代可能已删除的孩子。然后调用 remove 一个已经被删除的孩子RemoveAllChildren()

更不用说这个错误的逻辑了。

if (endelems is Text && elems.InnerText == e_Ver1)//e_Ver1 = "(/Ver1)"
{
    ...
else
{
    Run d_Run = (Run)endelems.Parent;
}

在 else 子句中,endelems 可能不会有一个为 a 的父级Run,因为它可能不是一个Text元素。

--- 编辑 --- 伪代码

IEnumerable<Text> elems = wd.MainDocumentPart.Document.Body.Descendants<Text>();
foreach (Text elem in elems) 
{

    if(elem.InnerText.Equals("Ver 1"))
    {
        IEnumerable<OpenXmlElement> afterelems = elem.ElementsAfter();
        foreach(OpenXmlElement openelem in afterelems)
        {
            if(openelem is Text && ((Text)openelem).InnerText.Equals("Ver 2"))
            {
                break;
            } else if(openelem is Text) {
                openelem.Remove();
            }
        }
        break;
    }

}

foreach (Run run in wd.MainDocumentPart.Document.Body.Descendants<Run>().Where(run => run.Descendants<Text>().Count() == 0 && run.Descendants<Break>().Count() == 0))
{
    run.Remove();
}

foreach (Paragraph par in wd.MainDocumentPart.Document.Body.Descendants<Paragraph>().Where(par => par.Descendants<Run>().Count() == 0 && par.Descendants<Table>().Count() == 0))
{
    par.Remove();
}
于 2013-04-24T14:04:35.750 回答