Простой способ конвертировать & # XXXX; из HTML в UTF-8 xml программно в .Net или с помощью инструментов - PullRequest
0 голосов
/ 03 августа 2010

HTML и XML не одинаковы, просто приведены для иллюстрации.

Для входного файла HTML

<p class=MsoNormal style='tab-stops:.5in'><b><span style='mso-tab-count:3'>                                    </span></b><b><span
lang=AR-SY dir=RTL style='mso-bidi-language:AR-SY'>&#1593;&#1586;&#1578;
&#1575;&#1576;&#1585;&#1575;&#1607;&#1610;&#1605;
&#1575;&#1604;&#1583;&#1608;&#1585;&#1610;</span><o:p></o:p></b></p>

получить XML с кодировкой UTF-8

<Name Type="Script"> صدام حسين التكريتي</Name>

В основном мне нужна последовательность ASCII sequence & # xxxx; & # yyyy; & # zzzz; быть сохраненным как utf-8.

1 Ответ

1 голос
/ 03 августа 2010

Я не совсем уверен, хотите ли вы преобразовать десятичную кодировку HTML на месте или выполнить преобразование из HTML в документ XML.Преобразование десятичных (или шестнадцатеричных) кодированных символов в UTF-8/16 не так уж сложно.Тем не менее, правильный анализ HTML в дикой природе может быть проблемой (см. thread ).

Здесь наивный класс для преобразования десятичных и шестнадцатеричных кодированных символов на месте и возврата строки .Net (я не даю никаких гарантий относительно ее правильности или надежности - особенно если вы пытаетесь использовать ее против некорректного HTML илисуррогатная пара символов):

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;

namespace HtmlEncodingConverter
{
    internal static class HtmlEncoding
    {
    private static readonly Regex EncodedCharRegex = new Regex(@"&#[X]?[0-9|A-F]{1,12};",
                                                               RegexOptions.Compiled |
                                                               RegexOptions.IgnoreCase |
                                                               RegexOptions.CultureInvariant);


    public static string ToUtfCharacters(string input)
    {
        return ConvertInnerText(input, ReplaceWithCharacter);
    }

    private static string ReplaceWithCharacter(string original)
    {
        return EncodedCharRegex.Replace(original, new MatchEvaluator(DecodeCharacter));
    }

    private static string DecodeCharacter(Match match)
    {
        string digits = match.ToString().TrimStart(new[] {'#', '&'}).TrimEnd(';').ToUpperInvariant();
        return digits.StartsWith("X") ? HexToString(digits) : DecToString(digits);
    }

    private static string DecToString(string digits)
    {
        return ((char) int.Parse(digits)).ToString();
    }

    private static string HexToString(string digits)
    {
        return ((char) int.Parse(
            digits.Substring(1), 
            NumberStyles.HexNumber, 
            CultureInfo.InvariantCulture)).ToString();
    }

    private static string ConvertInnerText(string original, Func<string, string> converter)
    {
        var convertedQueue = new Queue<char>(original.Length);
        var innerQueue = new Queue<char>();
        int tagCount = 0;
        bool hasFoundHtml = false;
        foreach (char character in original)
        {
            if (character.Equals('<'))
            {
                hasFoundHtml = true;
                if (tagCount == 0 && innerQueue.Count > 0)
                {
                    var innerString = new string(innerQueue.ToArray());
                    string convertedString = converter.Invoke(innerString);
                    foreach (char convertedCharacter in convertedString)
                    {
                        convertedQueue.Enqueue(convertedCharacter);
                    }
                    innerQueue.Clear();
                }
                tagCount += 1;
                convertedQueue.Enqueue(character);
                continue;
            }
            if (character.Equals('>'))
            {
                tagCount -= 1;
                convertedQueue.Enqueue(character);
                continue;
            }
            if (tagCount == 0 && hasFoundHtml)
            {
                innerQueue.Enqueue(character);
            }
            else
            {
                convertedQueue.Enqueue(character);
            }
        }
        return new string(convertedQueue.ToArray());
    }
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...