SORU
1 EKİM 2008, ÇARŞAMBA


En iyi XML kodlama metin veri yolu

Genel bir yöntem arıyordum .Net Xml öğe veya öznitelik kullanmak için bir dize kodlamak için, ve hemen bir tane bulamadım ettiğinde şaşırdı. Çok fazla ileri gitmeden, sadece dahili fonksiyonu eksik olabilir?

Gerçekten var olmayan bir an için varsayarak, EncodeForXml(string data) kendi genel yöntemim kuruyorum, ve bunu yapmak için en iyi yolu düşünüyorum.

Bütün bu şeyler istenir kullanıyorum veri &, < gibi kötü karakterler içerebilir;, " vb. Ayrıca vesilesiyle doğru kaçtı varlıkları içerir: &, < ve " sadece bir CDATA bölümü kullanarak iyi bir fikir olmayabilir demektir. Bu tür klunky anyay görünüyor; daha ziyade doğrudan xml olarak kullanılabilecek güzel bir dize ile bitirmek istiyorum.

Ben de kullandım bir düzenli ifade içinde geçmişe sadece yakalamak kötü ve işaretleri, ve düşündüğümü kullanarak onu yakalamak için onları bu durumda olduğu gibi ilk adım, ve sonra işin basit değiştirmek için diğer karakterler.

Bu daha da çok karmaşık yapmadan optimize edilmiş olabilir, ve orada kaçırdığım bir şey var mı? :

Function EncodeForXml(ByVal data As String) As String
    Static badAmpersand As new Regex("&(?![a-zA-Z]{2,6};|#[0-9]{2,4};)")

    data = badAmpersand.Replace(data, "&")

    return data.Replace("<", "<").Replace("""", """).Replace(">", "gt;")
End Function

Üzgünüm seni C# -tek millet ... ben pek dikkat eden bir dil kullanırım, ama yapmak istiyordum normal ifade statik ve bunu yapamazsın C# olmadan ilan dışında bir yöntemi, yani bu olacak VB.Net

Son olarak, hala devam ediyoruz .Çalıştığım 2.0 Net, ama eğer birinin son ürünü alıp, string sınıfı için bir uzantısı yöntemi de olabilir, güzel de olur.

Güncellemeİlk birkaç tepkiler gösteriyor .Net gerçekten yerleşik bunu yapmanın birçok yolu var. Ama başladım artık, bir şekilde kendime EncodeForXml bitirmek istiyorum() sadece eğlenmek için yöntem, bu yüzden hala iyileştirme için fikir arıyorum. Özellikle: varlıklar (belki de göster/liste halinde depolanan bir işin daha iyi performans alır bir şey olarak kodlanmış karakterler, daha kapsamlı bir listesi .() Yerine seri değişmez dizeler.

CEVAP
8 NİSAN 2009, ÇARŞAMBA


Giriş hakkında bilmek ne kadar bağlı olarak, not all Unicode characters are valid XML characters dikkate almak zorunda kalabilirsiniz.

Her ikisi deServer.HtmlEncodeveSistem.Güvenlik.SecurityElement.Kaçışgeçersiz XML karakterler, süre görmezden görünüyorSistem.XML.XmlWriter.WriteStringbir atarArgumentExceptiongeçersiz karakterler, bu durumda onları yok sayıyor kontrolü devre dışı sürece) ile karşılaştığında. Kütüphane fonksiyonları genel bakış here mevcuttur.

2011/8/14 düzenleme:en azından birkaç kişi son birkaç yıl içinde bu cevap danışmaları görmek, tamamen sayısız sorunları, horribly mishandling UTF-16 dahil olan orijinal kodu yeniden yazmaya karar verdim.

/// <summary>
/// Encodes data so that it can be safely embedded as text in XML documents.
/// </summary>
public class XmlTextEncoder : TextReader {
    public static string Encode(string s) {
        using (var stream = new StringReader(s))
        using (var encoder = new XmlTextEncoder(stream)) {
            return encoder.ReadToEnd();
        }
    }

    /// <param name="source">The data to be encoded in UTF-16 format.</param>
    /// <param name="filterIllegalChars">It is illegal to encode certain
    /// characters in XML. If true, silently omit these characters from the
    /// output; if false, throw an error when encountered.</param>
    public XmlTextEncoder(TextReader source, bool filterIllegalChars=true) {
        _source = source;
        _filterIllegalChars = filterIllegalChars;
    }

    readonly Queue<char> _buf = new Queue<char>();
    readonly bool _filterIllegalChars;
    readonly TextReader _source;

    public override int Peek() {
        PopulateBuffer();
        if (_buf.Count == 0) return -1;
        return _buf.Peek();
    }

    public override int Read() {
        PopulateBuffer();
        if (_buf.Count == 0) return -1;
        return _buf.Dequeue();
    }

    void PopulateBuffer() {
        const int endSentinel = -1;
        while (_buf.Count == 0 && _source.Peek() != endSentinel) {
            // Strings in .NET are assumed to be UTF-16 encoded [1].
            var c = (char) _source.Read();
            if (Entities.ContainsKey(c)) {
                // Encode all entities defined in the XML spec [2].
                foreach (var i in Entities[c]) _buf.Enqueue(i);
            } else if (!(0x0 <= c && c <= 0x8) &&
                       !new[] { 0xB, 0xC }.Contains(c) &&
                       !(0xE <= c && c <= 0x1F) &&
                       !(0x7F <= c && c <= 0x84) &&
                       !(0x86 <= c && c <= 0x9F) &&
                       !(0xD800 <= c && c <= 0xDFFF) &&
                       !new[] { 0xFFFE, 0xFFFF }.Contains(c)) {
                // Allow if the Unicode codepoint is legal in XML [3].
                _buf.Enqueue(c);
            } else if (char.IsHighSurrogate(c) &&
                       _source.Peek() != endSentinel &&
                       char.IsLowSurrogate((char) _source.Peek())) {
                // Allow well-formed surrogate pairs [1].
                _buf.Enqueue(c);
                _buf.Enqueue((char) _source.Read());
            } else if (!_filterIllegalChars) {
                // Note that we cannot encode illegal characters as entity
                // references due to the "Legal Character" constraint of
                // XML [4]. Nor are they allowed in CDATA sections [5].
                throw new ArgumentException(
                    String.Format("Illegal character: '{0:X}'", (int) c));
            }
        }
    }

    static readonly Dictionary<char,string> Entities =
        new Dictionary<char,string> {
            { '"', """ }, { '&', "&"}, { '\'', "'" },
            { '<', "<" }, { '>', ">" },
        };

    // References:
    // [1] http://en.wikipedia.org/wiki/UTF-16/UCS-2
    // [2] http://www.w3.org/TR/xml11/#sec-predefined-ent
    // [3] http://www.w3.org/TR/xml11/#charsets
    // [4] http://www.w3.org/TR/xml11/#sec-references
    // [5] http://www.w3.org/TR/xml11/#sec-cdata-sect
}

Birim testleri ve tam kodu here bulunabilir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Ben Schoon

    Ben Schoon

    23 Kasım 2012
  • bigky226

    bigky226

    11 HAZİRAN 2006
  • Tahir Jahi

    Tahir Jahi

    6 Mart 2006