2009-07-25 9 views
0

私は* slnファイル形式と同様の構成の形式を持っているので、一例として、次のことを取る:マルチレベルの「ノード」をテキストでどのように解析しますか?

DCOM Productions Configuration File, Format Version 1.0 

BeginSection:Global 
    GlobalKeyA = AnswerOne 

    .: Stores the global configuration key 
    :: for the application. This key is used 
    :: to save the current state of the app. 
    :: as well as prevent lockups 
    GlobalKey3 = AnswerTwo 

    .: Secondary Key. See above setting 
    GlobalKeyC = AnswerThree 

    BeginSection: UpdateSystem 
     NestedKeyA = One 
     NestedKeyB = Two 
     NestedKeyC = { A set of multiline data 
         where we will show how 
         to write a multiline 
         paragraph } 
     NestedKeyD = System.Int32, 100 
    EndSection 
EndSection 

BeginSection:Application 
    InstallPath = C:\Program Files\DCOM Productions\BitFlex 
EndSection 

私はそうパラメータとしてテキストのセグメントを取るおそらく再帰関数が必要になることを知って、例えば、セクション全体を渡し、そのように再帰的に解析します。

私はこれを行う方法について私の頭を得ることができないようです。各セクションには潜在的に多くの子セクションがあります。これはXML文書のようなものです。私は実際にここでコードを要求しているわけではなく、このような文書を解析する方法についての方法論です。

私はどのセクションで作業しているかを判断するためにタブ(インデックスを指定)を使用することを考えていましたが、ドキュメントがタブ付き(書式設定)されていないと失敗します。どんな良い考え?

答えて

2

おそらく、この形式とXMLの間で平行を描くことができます。 すなわち BeginSection < ==> "<オープニング>" EndSection < ==> "< /クロージング>" 多くのルート要素を持つXMLファイルとしての

と思います。 内側にあるものBeginSectionとEndSectionは内側のxmlノードになります。たとえば、 NestedKeyA =ノード名、値の1つです。

。:コメントはありませんので、スキップすることができます。 可能System.Int32、100 - 属性と{私達は複数行 段落の書き方を 表示されます複数行のデータ のセット}ノード

の値を指定できます - あなたが解析するアルゴリズムで出てくることができますこれもまた。

+0

うん、開始とEndSectionの基本的エンドストップ・ノードを起動しているが、どのように私はEndSectionがBeginSectionどの属する区別でしょうか?最初のノードを取得することはできませんでした。なぜなら、最初のノードを解析するのではなく、入れ子ノードのEndSectionになる可能性があるからです。 –

+0

1つのBeginSectionを解析するパーサを作成し、BeginSection内のBeginSectionに出会った場合は、新しいサブセクションの先頭で自身を呼び出します。結果をハッシュリファレンスとして渡します。ハッシュリファレンスは、呼び出し元関数のハッシュに追加することができます。 – Sorantis

+0

洞察力に感謝します。私は今これについてどうやって行くのか分かっていると思うし、他に質問があればポストバックすると思う。ありがとう! –

0

よろしくお願いします。 * あー *

/// <summary> 
/// Reads and parses xdf strings 
/// </summary> 
public sealed class XdfReader { 
    /// <summary> 
    /// Instantiates a new instance of the DCOMProductions.BitFlex.IO.XdfReader class. 
    /// </summary> 
    public XdfReader() { 
     // 
     // TODO: Any constructor code here 
     // 
    } 

    #region Constants 

    /// <devdoc> 
    /// This regular expression matches against a section beginning. A section may look like the following: 
    /// 
    ///  SectionName:Begin 
    ///  
    /// Where 'SectionName' is the name of the section, and ':Begin' represents that this is the 
    /// opening tag for the section. This allows the parser to differentiate between open and 
    /// close tags. 
    /// </devdoc> 
    private const String SectionBeginRegularExpression = @"[0-9a-zA-Z]*:Begin"; 

    /// <devdoc> 
    /// This regular expression matches against a section ending. A section may look like the following: 
    /// 
    ///  SectionName:End 
    ///  
    /// Where 'SectionName' is the name of the section, and ':End' represents that this is the 
    /// closing tag for the section. This allows the parser to differentiate between open and 
    /// close tags. 
    /// </devdoc> 
    private const String SectionEndRegularExpression = @"[0-9a-zA-Z]*:End"; 

    /// <devdoc> 
    /// This regular expression matches against a key and it's value. A key may look like the following: 
    /// 
    ///  KeyName=KeyValue 
    ///  KeyName = KeyValue 
    ///  KeyName =KeyValue 
    ///  KeyName= KeyValue 
    ///  KeyName =  KeyValue 
    ///     
    /// And so on so forth. This regular expression matches against all of these, where the whitespace 
    /// former and latter of the assignment operator are optional. 
    /// </devdoc> 
    private const String KeyRegularExpression = @"[0-9a-zA-Z]*\s*?=\s*?[^\r]*"; 

    #endregion 

    #region Methods 

    public void Flush() { 
     throw new System.NotImplementedException(); 
    } 

    private String GetSectionName(String xdf) { 
     Match sectionMatch = Regex.Match(xdf, SectionBeginRegularExpression); 

     if (sectionMatch.Success) { 
      String retVal = sectionMatch.Value; 
      retVal = retVal.Substring(0, retVal.IndexOf(':')); 
      return retVal; 
     } 
     else { 
      throw new BitFlex.IO.XdfException("The specified xdf did not contain a valid section."); 
     } 
    } 

    public XdfFile ReadFile(String fileName) { 
     throw new System.NotImplementedException(); 
    } 

    public XdfKey ReadKey(String xdf) { 
     Match keyMatch = Regex.Match(xdf, KeyRegularExpression); 

     if (keyMatch.Success) { 
      String name = keyMatch.Value.Substring(0, keyMatch.Value.IndexOf('=')); 
      name = name.TrimEnd(' '); 

      XdfKey retVal = new XdfKey(name); 

      String value = keyMatch.Value.Remove(0, keyMatch.Value.IndexOf('=') + 1); 
      value = value.TrimStart(' '); 

      retVal.Value = value; 
      return retVal; 
     } 
     else { 
      throw new BitFlex.IO.XdfException("The specified xdf did not contain a valid key."); 
     } 
    } 

    public XdfSection ReadSection(String xdf) { 
     if (ValidateSection(xdf)) { 
      String[] rows = xdf.Split(new String[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); 
      XdfSection rootSection = new XdfSection(GetSectionName(rows[0])); System.Diagnostics.Debug.WriteLine(rootSection.Name); 

      do { 
       Match beginMatch = Regex.Match(xdf, SectionBeginRegularExpression); 
       beginMatch = beginMatch.NextMatch(); 

       if (beginMatch.Success) { 
        Match endMatch = Regex.Match(xdf, String.Format("{0}:End", GetSectionName(beginMatch.Value))); 

        if (endMatch.Success) { 
         String sectionXdf = xdf.Substring(beginMatch.Index, (endMatch.Index + endMatch.Length) - beginMatch.Index); 
         xdf = xdf.Remove(beginMatch.Index, (endMatch.Index + endMatch.Length) - beginMatch.Index); 

         XdfSection section = ReadSection(sectionXdf); System.Diagnostics.Debug.WriteLine(section.Name); 

         rootSection.Sections.Add(section); 
        } 
        else { 
         throw new BitFlex.IO.XdfException(String.Format("There is a missing section ending at index {0}.", endMatch.Index)); 
        } 
       } 
       else { 
        break; 
       } 
      } while (true); 

      MatchCollection keyMatches = Regex.Matches(xdf, KeyRegularExpression); 

      foreach (Match item in keyMatches) { 
       XdfKey key = ReadKey(item.Value); 
       rootSection.Keys.Add(key); 
      } 

      return rootSection; 
     } 
     else { 
      throw new BitFlex.IO.XdfException("The specified xdf did not contain a valid section."); 
     } 
    } 

    private Boolean ValidateSection(String xdf) { 
     String[] rows = xdf.Split(new String[] { "\r\n" }, StringSplitOptions.None); 

     if (Regex.Match(rows[0], SectionBeginRegularExpression).Success) { 
      if (Regex.Match(rows[rows.Length - 1], SectionEndRegularExpression).Success) { 
       return true; 
      } 
      else { 
       return false; 
      } 
     } 
     else { 
      return false; 
     } 
    } 

    #endregion 
} 

}

関連する問題