0

HTMLAgility、C#、XMLを使用する

私はHTMLAgilityを使用してWebページをスクレイプし、次にクラス構造にデータを入力します。クラス構造はXMLドキュメントにシリアル化されます。

私が扱っているデータはギターコードであるため、管理する特殊文字がいくつかあります。

私が苦労している特殊文字は、前の文字列の真ん中の文字「Aº7」です(これは音楽的には減少していることを意味します)。

Webページから文字列を取得すると、ウォッチウィンドウの黒いひし形に疑問符が表示されます。これがXMLに入力されます。

私の選択は次のとおりです。a)文字を適切に処理して、XMLで文字として表示されるようにします。b)文字列内のこのcharのすべてのインスタンスを単語「dim」に変換します

charはreplaceステートメントで検出されるため(char(code)を使用)、これを実行するための最良の方法は何ですか。

この問題にどのように取り組むべきか、私にはよくわかりません。

データを取得するために使用している以下のコード(わかりやすくするために、これは一度だけ実行された関数であり、使用可能な形式のデータを取得すると、二度と使用されることはありません!、xmlシリアル化オブジェクト構造を作成するために構築されただけです)。

        public void BuildDBFromWebSite()
    {
        string[] chordKeys = { "A", "A#", "Ab", "B", "Bb", "C", "C#", "D", "D#", "Db", "E", "Eb", "F", "F#", "G", "G#", "Gb" };

        HtmlWeb web = new HtmlWeb();
        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();

        foreach (string chordKeyName in chordKeys)
        {
            //LOOP THROUGH THE CHORD KEYS
            chordKey theChordKey = new chordKey() { KeyName = chordKeyName };
            _keys.Add(theChordKey);

            //grab the tone page
            doc = web.Load("http://www.scales-chords.com/showchbykey.php?key=" + theChordKey.KeyName);

            HtmlNode chordListTable = doc.DocumentNode.SelectSingleNode("/html/body/div[@id='wrapper']/div[@id='body']/div[@id='left']/div[@id='visit']/table/tbody");            

            //  CHORDS
            HtmlNodeCollection chordRows = chordListTable.SelectNodes("tr");

            for (int i = 2; i < chordRows.Count; i++)
            {
                //LOOP THROUGH THE CHORDS
                Chord theChord = new Chord();

                HtmlNodeCollection chordInfoCells = chordRows[i].SelectNodes("td");
                HtmlNode chordLink = chordInfoCells[0].SelectSingleNode("a[@href]");

                //each of the next 3 cells can contain a bad glyph for diminished chords
                theChord.ChordName = chordInfoCells[0].InnerText;
                theChord.ChordNameText = chordInfoCells[1].InnerText;
                theChord.Family = chordInfoCells[2].InnerText;
                theChord.Importance = chordInfoCells[3].InnerText;

                //HtmlAgilityPack.HtmlAttribute href = chordLink.Attributes["href"];
                //HTMLAgility tries to encode the bad glyph but uses the wrong escape and breaks the href, work around is to manually strip the href myself
                string theURL = chordLink.OuterHtml;
                theURL = theURL.Remove(0,9);
                int startPos = theURL.IndexOf(">") - 1;

                theURL = theURL.Substring(0, startPos);

                const string theBadCode = "º";

                theChord.ChordNameURL = HTMLEncodeSpecialChars(theURL);
                theChordKey.Chords.Add(theChord);
            }

            //VARIATIONS ETC
            foreach (Chord theChord in theChordKey.Chords)
            {
                //grab the tone page
                doc = web.Load("http://www.scales-chords.com/" + theChord.ChordNameURL);

                HtmlNode chordMoreInfoTable = doc.DocumentNode.SelectSingleNode("/html/body/div[@id='wrapper']/div[@id='body']/div[@id='left']/div[@id='visit']/center/table[1]/tbody");
                HtmlNodeCollection chordMoreInfoRows = chordMoreInfoTable.SelectNodes("tr");

                theChord.Notes = chordMoreInfoRows[3].SelectNodes("td")[1].InnerText;
                theChord.Structure = chordMoreInfoRows[4].SelectNodes("td")[1].InnerText;
                theChord.BelongsTo = chordMoreInfoRows[6].SelectNodes("td")[1].InnerText;

                HtmlNodeCollection variationHTML = doc.DocumentNode.SelectNodes("/html/body/div[@id='wrapper']/div[@id='body']/div[@id='left']/div[@id='visit']/center/b");

                for (int iVariation = 1; iVariation < variationHTML.Count; iVariation=iVariation+2)
                {
                    Variation theVariation = new Variation();

                    theVariation.Notation = variationHTML[iVariation].NextSibling.InnerHtml;
                    theVariation.Difficuty = variationHTML[iVariation + 1].NextSibling.InnerText;

                    string[] theStrings = theVariation.Notation.Split(' ');
                    try
                    {
                        theVariation.String1 = theStrings[1];
                        theVariation.String2 = theStrings[2];
                        theVariation.String3 = theStrings[3];
                        theVariation.String4 = theStrings[4];
                        theVariation.String5 = theStrings[5];
                        theVariation.String6 = theStrings[6];
                    }
                    catch (Exception ex)
                    {

                    }
                    theChord.Variations.Add(theVariation);

                    Console.WriteLine(theChord.ChordNameText + " : " + theVariation.Notation);
                }
            }
        }

        this.SaveToDisk("C:\\chords.xml");
    }

ありがとう

ダン

4

1 に答える 1

1

あなたが抱えている問題は、おそらくエンコーディングが原因です。このページには、文字セットを使用していると記載されているため、windows-1252このようにコードを変更すると機能するはずです。

WebClient client = new WebClient();
client.Encoding = System.Text.Encoding.GetEncoding("windows-1252");
doc = web.Load(client.OpenRead("http://www.scales-chords.com/showchbykey.php?key=" + theChordKey.KeyName));

もちろん、この関数を複数回使用する場合は、WebClientインスタンスの宣言をforeachから移動します。

于 2012-04-27T23:53:38.340 に答える