3

W3 仕様に準拠した簡単な実装を作成しました。ここでは、さまざまな有効な文字のセットを保持し (有効な開始文字は後続の文字とは異なります)、string.Contains を使用します。しかし、正当な文字のセットは驚くほど (とにかく私には) 大きく、候補文字列の文字を一度にチェックするだけでも、少しコストがかかります。

バッチの実行ごとに(数秒、数分、または数時間かかる)いくつかの文字列を1回(数ミリ秒)検証する必要があるため、これは現時点では実際には問題ではありませんが、他の人が何を提案するか知りたいです.

これが私の簡単な実装です。

using System;
using System.Text;
using Project.Common; // Guard

namespace Project.Common.XmlUtilities
{
    static public class XmlUtil
    {
        static public bool IsLegalElementName(string localName)
        {
            Guard.ArgumentNotNull(localName, "localName");
            if (localName == "") 
                return false;

            if (NameStartChars.IndexOf(localName[0]) == -1)
                return false;

            for (int i = 1; i < localName.Length; i++)
                if (NameChars.IndexOf(localName[i]) == -1)
                    return false;

            return true;
        }


        // See W3 spec at http://www.w3.org/TR/REC-xml/#NT-NameStartChar.
        static public readonly string NameStartChars = AZ.ToLower() + AZ + ":_" + GetStringFromCharRanges(0xC0, 0xD6, 0xD8, 0xF6, 0xF8, 0x2FF, 0x370, 0x37D, 0x37F, 0x1FFF, 0x200C, 0x200D, 0x2070, 0x218F, 0x2C00, 0x2FEF, 0x3001, 0xD7FF, 0xF900, 0xFDCF, 0xFDF0, 0xFFFD, 0x10000, 0xEFFFF);

        // See W3 spec at http://www.w3.org/TR/REC-xml/#NT-NameChar.
        static public readonly string NameChars = NameStartChars + "-.0123456789" + char.ConvertFromUtf32(0xB7) + GetStringFromCharRanges(0x0300, 0x036F, 0x203F, 0x2040);

        public const string AZ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        // Hacky but convenient: alternating low-high unicode points specifies multiple ranges, e.g. 0-5 and 10-12 would be 0, 5, 10, 12.
        static string GetStringFromCharRanges(params int[] lowHigh)
        {
            var sb = new StringBuilder();
            for (int i = 0; i < lowHigh.Length; i += 2)
            {
                int low = lowHigh[i];
                int high = lowHigh[i + 1];
                for (int ci=low; ci < high; ci++)
                    sb.Append(char.ConvertFromUtf32(ci));
            }
            return sb.ToString();
        }
    }
}

私はそれを構築することを気にしませんでしたが、タイプ初期化子で一度ソートされたリストを作成し、リストをバイナリ検索して (string.Contains で線形検索するのではなく)、各文字がスペースと時間のバランスが取れていることを確認します。そして複雑さ。しかし、おそらく他に (より良い!) アイデアがありますか?

4

2 に答える 2

0

正規表現を使用するか、単に問題の名前で XElement を作成しようとします (例外がある場合、名前は無効です...)

于 2013-06-05T10:00:16.050 に答える