2014-10-27 68 views
2

只是好奇的是,如果有更簡化的版本來檢查給定的機構是否具有應用「Heading3」的單詞樣式,因爲我寫了學習OpenXML庫的示例C#代碼。清楚的是,我只是要求給定一個body元素,我怎樣才能確定給定body元素是否應用了什麼樣的文字風格。我最終必須編寫一個程序來處理大量的.DOCX文件,並且需要從頂部到底部處理它們。C#OpenXml獲取DOCX WordStyle屬性簡化代碼

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Wordprocessing; 
using System.IO; 

namespace docxparsing 
{ 
    class Program 
    { 
    static void Main() 
    { 
     string file_to_parse = @"C:\temp\sample.docx"; 

     WordprocessingDocument doc = WordprocessingDocument.Open(file_to_parse,false); 

     Body body = doc.MainDocumentPart.Document.Body; 

     string fooStr 
     foreach(var foo in body) 
     { 
      fooStr = foo.InnerXml; 

      /* 
          these 2 comments represent 2 different xml snippets from 'fooStr'. the only way i figure out how to get the word style is by reading 
            this xml and doing checks for values. i don't know of any other approach in using the body element to check for the applied word style 

       <w:pPr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:pStyle w:val="Heading2" /> 
       <w:pPr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:pStyle w:val="Heading3" /> 
      */ 

      bool hasHeading3 = fooStr.Contains("pStyle w:val=\"Heading3\""); 

      if (hasHeading3) 
      { 
       Console.WriteLine("heading3 found"); 
      } 
     } 

     doc.Close(); 
    } 
} 

}

// ------------------------------------ -------------------------------------------

EDIT

這裏是更新一種方法的代碼。仍然不總是滿意,但它的作品。功能看是getWordStyleValue(串x)

using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Wordprocessing; 
using System; 
using System.Diagnostics; 
using System.IO; 
using System.Text; 


namespace docxparsing 
{ 
    class Program 
    { 
     // ************************************************ 
     // grab the word style value 
     // ************************************************ 
     static string getWordStyleValue(string x) 
     { 
      int p = 0; 
      p = x.IndexOf("w:pStyle w:val="); 
      if (p == -1) 
      { 
       return ""; 
      } 
      p = p + 15; 

      StringBuilder sb = new StringBuilder(); 
      while (true) 
      { 
       p++; 
       char c = x[p]; 
       if (c != '"') 
       { 
        sb.Append(c); 
       } 
       else 
       { 
        break; 
       } 
      } 

      string s = sb.ToString(); 
      return s; 
     } 


     // ************************************************ 
     // Main 
     // ************************************************ 
     static void Main(string[] args) 
     { 
      string theFile = @"C:\temp\sample.docx"; 
      WordprocessingDocument doc = WordprocessingDocument.Open(theFile,false); 

      string body_table  = "DocumentFormat.OpenXml.Wordprocessing.Table"; 
      string body_paragraph = "DocumentFormat.OpenXml.Wordprocessing.Paragraph"; 

      Body body = doc.MainDocumentPart.Document.Body; 
      StreamWriter sw1 = new StreamWriter("paragraphs.log"); 

      foreach (var b in body) 
      { 
       string body_type = b.ToString(); 

       if (body_type == body_paragraph) 
       { 
        string str = getWordStyleValue(b.InnerXml); 

        if (str == "" || str == "HeadingNon-TOC" || str == "TOC1" || str == "TOC2" || str == "TableofFigures" || str == "AcronymList") 
        { 
         continue; 
        } 

        sw1.WriteLine(str + "," + b.InnerText); 
       } 

       if (body_type == body_table) 
       { 
      //  sw1.WriteLine("Table:\n{0}",b.InnerText); 
       } 
      } 

      doc.Close(); 
      sw1.Close(); 
     } 
    } 
} 
+0

注:如果你的目標是隻確定「heading3」在文檔中使用的所有,你可以找到'第一次出現後break'。 – 2014-10-27 17:57:59

+0

嗨@MattBurland,感謝評論,但這不是我的最終目標。我最終必須做的是處理N.DOCX文件,轉換數據並將它們導入到專有的平面文件數據庫中。解析的方式將工作是我必須根據單詞樣式xt,基於單詞樣式qw的動作B,等等...... – dxlguru 2014-10-27 18:06:10

+1

這可能最終是相關的,'Heading3'是語言特定的並且來自文檔用英文版的Word創建。其他Word語言版本將在這裏具有語言特定的內容(而不是'Heading3'它可以'berschrift3')。從'Heading 3'到'styleId'的映射可以在'styles.xml'中找到,也就是'StyleDefinitionsPart'。 – 2014-10-28 19:13:26

回答

2

是。你可以做這樣的事情:(在XML w:pStyle

bool ContainsHeading3 = body.Descendants<ParagraphSytleId>().Any(psId => psId.Val == "Heading3"); 

這將着眼於所有ParagraphStyleId元素,看看是否其中任何Heading3Val

+0

謝謝。我很瞭解代碼。精通C#,但只是學習這個OpenXml SDK。儘管爲了我的需要去修改它。 – dxlguru 2014-10-27 18:09:44

1

剛剛粘貼這個編輯從原來的帖子,所以他有更好的知名度。

這是我想出的一個解決方案。是的,它有點cody(如果這是一個詞),但工作LINQ(我最喜歡)優化一個更優雅的解決方案。

-

這是更新代碼的一種方法。仍然不總是滿意,但它的作品。功能看是getWordStyleValue(串x)

using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Wordprocessing; 
using System; 
using System.Diagnostics; 
using System.IO; 
using System.Text; 


namespace docxparsing 
{ 
    class Program 
    { 
     // ************************************************ 
     // grab the word style value 
     // ************************************************ 
     static string getWordStyleValue(string x) 
     { 
      int p = 0; 
      p = x.IndexOf("w:pStyle w:val="); 
      if (p == -1) 
      { 
       return ""; 
      } 
      p = p + 15; 

      StringBuilder sb = new StringBuilder(); 
      while (true) 
      { 
       p++; 
       char c = x[p]; 
       if (c != '"') 
       { 
        sb.Append(c); 
       } 
       else 
       { 
        break; 
       } 
      } 

      string s = sb.ToString(); 
      return s; 
     } 


     // ************************************************ 
     // Main 
     // ************************************************ 
     static void Main(string[] args) 
     { 
      string theFile = @"C:\temp\sample.docx"; 
      WordprocessingDocument doc = WordprocessingDocument.Open(theFile,false); 

      string body_table  = "DocumentFormat.OpenXml.Wordprocessing.Table"; 
      string body_paragraph = "DocumentFormat.OpenXml.Wordprocessing.Paragraph"; 

      Body body = doc.MainDocumentPart.Document.Body; 
      StreamWriter sw1 = new StreamWriter("paragraphs.log"); 

      foreach (var b in body) 
      { 
       string body_type = b.ToString(); 

       if (body_type == body_paragraph) 
       { 
        string str = getWordStyleValue(b.InnerXml); 

        if (str == "" || str == "HeadingNon-TOC" || str == "TOC1" || str == "TOC2" || str == "TableofFigures" || str == "AcronymList") 
        { 
         continue; 
        } 

        sw1.WriteLine(str + "," + b.InnerText); 
       } 

       if (body_type == body_table) 
       { 
      //  sw1.WriteLine("Table:\n{0}",b.InnerText); 
       } 
      } 

      doc.Close(); 
      sw1.Close(); 
     } 
    } 
}