代码之家  ›  专栏  ›  技术社区  ›  MicMit

在.NET中以编程方式或使用工具轻松地将&XXXX;从HTML转换为UTF-8 XML

  •  0
  • MicMit  · 技术社区  · 14 年前

    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>
    

    接收带UTF-8编码的XML

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

    基本上,我需要一个序列ascii序列&XXXX;YYYY;&Zzz;保存为utf-8。

    1 回复  |  直到 14 年前
        1
  •  1
  •   Community CDub    7 年前

    我不太确定您是要就地转换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());
        }
    }
    }