Làm cách nào để xóa các ký tự thập lục phân không hợp lệ khỏi nguồn dữ liệu dựa trên XML trước khi xây dựng một XmlReader hoặc XPathDocument sử dụng dữ liệu?


76

Có cách nào dễ dàng / chung chung để làm sạch nguồn dữ liệu dựa trên XML trước khi sử dụng nó trong XmlReader để tôi có thể sử dụng dữ liệu XML không tuân theo các giới hạn ký tự thập lục phân được đặt trên XML một cách dễ dàng không?

Ghi chú:

  • Giải pháp cần xử lý các nguồn dữ liệu XML sử dụng các mã hóa ký tự không phải UTF-8, ví dụ bằng cách chỉ định mã hóa ký tự tại khai báo tài liệu XML. Không thay đổi mã hóa ký tự của nguồn trong khi loại bỏ các ký tự thập lục phân không hợp lệ là một điểm mấu chốt chính.
  • Việc xóa các ký tự thập lục phân không hợp lệ sẽ chỉ xóa các giá trị được mã hóa thập lục phân, vì bạn thường có thể tìm thấy các giá trị href trong dữ liệu có chứa một chuỗi sẽ là một chuỗi khớp với một ký tự thập lục phân.

Lý lịch:

Tôi cần sử dụng nguồn dữ liệu dựa trên XML phù hợp với một định dạng cụ thể (nghĩ rằng nguồn cấp dữ liệu Atom hoặc RSS), nhưng muốn có thể sử dụng các nguồn dữ liệu đã được xuất bản chứa các ký tự thập lục phân không hợp lệ theo đặc tả XML.

Trong .NET nếu bạn có một Luồng đại diện cho nguồn dữ liệu XML và sau đó cố gắng phân tích cú pháp nó bằng XmlReader và / hoặc XPathDocument, thì một ngoại lệ sẽ xuất hiện do việc đưa các ký tự thập lục phân không hợp lệ vào dữ liệu XML. Nỗ lực hiện tại của tôi để giải quyết vấn đề này là phân tích cú pháp Luồng dưới dạng một chuỗi và sử dụng một biểu thức chính quy để xóa và / hoặc thay thế các ký tự thập lục phân không hợp lệ, nhưng tôi đang tìm kiếm một giải pháp hiệu quả hơn.

Câu trả lời:


76

có thể không hoàn hảo (nhấn mạnh thêm vì mọi người thiếu tuyên bố từ chối trách nhiệm này), nhưng những gì tôi đã làm trong trường hợp đó là bên dưới. Bạn có thể điều chỉnh để sử dụng với một luồng.

/// <summary>
/// Removes control characters and other non-UTF-8 characters
/// </summary>
/// <param name="inString">The string to process</param>
/// <returns>A string with no control characters or entities above 0x00FD</returns>
public static string RemoveTroublesomeCharacters(string inString)
{
    if (inString == null) return null;

    StringBuilder newString = new StringBuilder();
    char ch;

    for (int i = 0; i < inString.Length; i++)
    {

        ch = inString[i];
        // remove any characters outside the valid UTF-8 range as well as all control characters
        // except tabs and new lines
        //if ((ch < 0x00FD && ch > 0x001F) || ch == '\t' || ch == '\n' || ch == '\r')
        //if using .NET version prior to 4, use above logic
        if (XmlConvert.IsXmlChar(ch)) //this method is new in .NET 4
        {
            newString.Append(ch);
        }
    }
    return newString.ToString();

}

1
hãy thử giải pháp của dnewcome bên dưới.
Eugene Katz

2
-1 câu trả lời này gây hiểu lầm vì nó loại bỏ các ký tự hợp lệ trong XML, không phải là các ký tự điều khiển và là UTF-8 hợp lệ.
Daniel Cassidy

2
Nếu bạn muốn cập nhật câu trả lời với nhiều bộ lọc tốt hơn, hãy làm như vậy. Như câu trả lời của tôi đã nói, nó có thể không hoàn hảo, nhưng nó phục vụ nhu cầu của tôi.
Eugene Katz

3
Tôi đã sử dụng XmlConvert.IsXmlChar (ch) cho bộ lọc của mình.
Brad J

1
@BradJ, điểm rất tốt. Phương thức này dường như đã được thêm vào .NET 4, vì vậy hãy chuyển mã để chỉ sử dụng phương thức đó trong ví dụ. Cảm ơn!
Eugene Katz

60

Tôi thích khái niệm danh sách trắng của Eugene. Tôi cần làm điều tương tự như áp phích gốc, nhưng tôi cần hỗ trợ tất cả các ký tự Unicode, không chỉ tối đa 0x00FD. Đặc tả XML là:

Char = # x9 | #xA | #xD | [# x20- # xD7FF] | [# xE000- # xFFFD] | [# x10000- # x10FFFF]

Trong .NET, đại diện bên trong của các ký tự Unicode chỉ là 16 bit, vì vậy chúng tôi không thể `` cho phép '0x10000-0x10FFFF một cách rõ ràng. Đặc tả XML rõ ràng không cho phép các điểm mã đại diện bắt đầu từ 0xD800 xuất hiện. Tuy nhiên, có thể là nếu chúng tôi cho phép các điểm mã thay thế này trong danh sách trắng của mình, mã hóa utf-8 cuối cùng chuỗi của chúng tôi có thể tạo ra XML hợp lệ miễn là mã hóa utf-8 thích hợp được tạo ra từ các cặp ký tự thay thế utf-16 trong Chuỗi .NET. Tuy nhiên, tôi chưa khám phá điều này, vì vậy tôi đã đặt cược an toàn hơn và không cho phép những người đại diện trong danh sách trắng của mình.

Tuy nhiên, các nhận xét trong giải pháp của Eugene là sai lầm, vấn đề là các ký tự chúng tôi đang loại trừ không hợp lệ trong XML ... chúng là các điểm mã Unicode hoàn toàn hợp lệ. Chúng tôi sẽ không xóa các ký tự không phải utf-8. Chúng tôi đang xóa các ký tự utf-8 có thể không xuất hiện trong các tài liệu XML được định dạng tốt.

public static string XmlCharacterWhitelist( string in_string ) {
    if( in_string == null ) return null;

    StringBuilder sbOutput = new StringBuilder();
    char ch;

    for( int i = 0; i < in_string.Length; i++ ) {
        ch = in_string[i];
        if( ( ch >= 0x0020 && ch <= 0xD7FF ) || 
            ( ch >= 0xE000 && ch <= 0xFFFD ) ||
            ch == 0x0009 ||
            ch == 0x000A || 
            ch == 0x000D ) {
            sbOutput.Append( ch );
        }
    }
    return sbOutput.ToString();
}

nó sẽ nối thêm & và điều này gây doc = XDocument.Load(@strXMLPath);ra ngoại lệ
CODError

1
xin chào, bạn có nghĩ rằng XmlConvert.IsXmlChar () sẽ chính xác hơn không? Câu trả lời của Eugene đã thay đổi kể từ bình luận cuối cùng của bạn. cảm ơn
DaFi4

30

Để loại bỏ các ký tự XML không hợp lệ, tôi khuyên bạn nên sử dụng phương thức XmlConvert.IsXmlChar . Nó đã được thêm vào từ .NET Framework 4 và cũng được trình bày trong Silverlight. Đây là mẫu nhỏ:

void Main() {
    string content = "\v\f\0";
    Console.WriteLine(IsValidXmlString(content)); // False

    content = RemoveInvalidXmlChars(content);
    Console.WriteLine(IsValidXmlString(content)); // True
}

static string RemoveInvalidXmlChars(string text) {
    char[] validXmlChars = text.Where(ch => XmlConvert.IsXmlChar(ch)).ToArray();
    return new string(validXmlChars);
}

static bool IsValidXmlString(string text) {
    try {
        XmlConvert.VerifyXmlChars(text);
        return true;
    } catch {
        return false;
    }
}

13

Triển khai KHÔ giải pháp của câu trả lời này (sử dụng một hàm tạo khác - hãy sử dụng một hàm bạn cần trong ứng dụng của mình):

public class InvalidXmlCharacterReplacingStreamReader : StreamReader
{
    private readonly char _replacementCharacter;

    public InvalidXmlCharacterReplacingStreamReader(string fileName, char replacementCharacter) : base(fileName)
    {
        this._replacementCharacter = replacementCharacter;
    }

    public override int Peek()
    {
        int ch = base.Peek();
        if (ch != -1 && IsInvalidChar(ch))
        {
            return this._replacementCharacter;
        }
        return ch;
    }

    public override int Read()
    {
        int ch = base.Read();
        if (ch != -1 && IsInvalidChar(ch))
        {
            return this._replacementCharacter;
        }
        return ch;
    }

    public override int Read(char[] buffer, int index, int count)
    {
        int readCount = base.Read(buffer, index, count);
        for (int i = index; i < readCount + index; i++)
        {
            char ch = buffer[i];
            if (IsInvalidChar(ch))
            {
                buffer[i] = this._replacementCharacter;
            }
        }
        return readCount;
    }

    private static bool IsInvalidChar(int ch)
    {
        return (ch < 0x0020 || ch > 0xD7FF) &&
               (ch < 0xE000 || ch > 0xFFFD) &&
                ch != 0x0009 &&
                ch != 0x000A &&
                ch != 0x000D;
    }
}

có lẽ tốt hơn nên sử dụng XmlConvert.IsXmlChar () qua các kiểm tra phạm vi ch? bạn nghĩ sao?
DaFi4,

@montewhizdoh: IsXmlChar là tính năng mới trong .NET 4. Nếu bạn có thể sử dụng, hãy thoải mái sử dụng. Giải pháp này là .NET 2.0+.
Neolisk

1
Cách tiếp cận tương tự mà tôi đã thực hiện cho bản thân mình, nhưng do tôi kế thừa từ Stream, đây không phải là một ý tưởng hay vì Stream.Read () hoạt động với mảng byte chứ không phải ký tự và việc kiểm tra các ký tự không phải là một cách thanh lịch. Giải pháp của bạn bằng cách kế thừa từ StreamReader tốt hơn, cảm ơn bạn!
Mar

1
+1 Bởi vì điều này cho phép đọc các tệp XML THỰC SỰ lớn (đã thử nghiệm thành công với các tệp 100MB). Các giải pháp tải mọi thứ vào một Chuỗi trước khi lọc ra các ký tự xấu không thành công với ngoại lệ OutOfMemory.
Brad Oestreicher

9

Hiện đại hóa câu trả lời của dnewcombe , bạn có thể thực hiện một cách tiếp cận đơn giản hơn một chút

public static string RemoveInvalidXmlChars(string input)
{
    var isValid = new Predicate<char>(value =>
        (value >= 0x0020 && value <= 0xD7FF) ||
        (value >= 0xE000 && value <= 0xFFFD) ||
        value == 0x0009 ||
        value == 0x000A ||
        value == 0x000D);

    return new string(Array.FindAll(input.ToCharArray(), isValid));
}

hoặc, với Linq

public static string RemoveInvalidXmlChars(string input)
{
    return new string(input.Where(value =>
        (value >= 0x0020 && value <= 0xD7FF) ||
        (value >= 0xE000 && value <= 0xFFFD) ||
        value == 0x0009 ||
        value == 0x000A ||
        value == 0x000D).ToArray());
}

Tôi muốn biết hiệu suất của các phương pháp này so sánh như thế nào và tất cả chúng đều so sánh như thế nào với phương pháp sử dụng danh sách đen Buffer.BlockCopy.


Tôi đã gặp sự cố với phương thức Linq ném System.OutOfMemoryException khi chuỗi XML trên các tệp XML lớn hơn.
Brad J

@BradJ có lẽ, chuỗi được truyền vào là rất dài trong những trường hợp đó?
Jodrell

@BradJ cuối cùng, một số loại chuyển đổi luồng sẽ tốt hơn, bạn có thể chuyển trực tiếp đến XmlReader.Createthay vì tải toàn bộ tệp vào một chuỗi trong bộ nhớ.
Jodrell

2
vừa thực hiện một bài kiểm tra tốc độ so với câu trả lời của dnewcombe và cả hai giải pháp của bạn đều nhanh hơn khoảng 3-4 lần với phiên bản Linq chỉ chậm hơn một chút so với phiên bản không phải Linux của bạn. Tôi đã không mong đợi sự khác biệt như vậy. đã sử dụng dây dài và 100k lần lặp với đồng hồ bấm giờ để tính thời gian.
Seer

@Seer Tôi đang sử dụng luồng ký tự có độ dài ~ 60k và giải pháp này hoạt động chậm hơn một chút so với phương thức StringBuilder, không chắc tôi đã làm gì khác.
adotout

5

Đây là câu trả lời của dnewcome trong StreamReader tùy chỉnh. Nó chỉ đơn giản bao bọc một trình đọc luồng thực và thay thế các ký tự khi chúng được đọc.

Tôi chỉ thực hiện một số phương pháp để tiết kiệm thời gian cho mình. Tôi đã sử dụng điều này kết hợp với XDocument.Load và một dòng tệp và chỉ phương thức Read (char [] buffer, int index, int count) được gọi, vì vậy nó hoạt động như thế này. Bạn có thể cần triển khai các phương pháp bổ sung để điều này hoạt động cho ứng dụng của bạn. Tôi đã sử dụng phương pháp này vì nó có vẻ hiệu quả hơn các câu trả lời khác. Tôi cũng chỉ triển khai một trong các hàm tạo, bạn rõ ràng có thể triển khai bất kỳ hàm tạo nào trong số các hàm tạo StreamReader mà bạn cần, vì nó chỉ là một chuyển qua.

Tôi đã chọn thay thế các ký tự hơn là loại bỏ chúng bởi vì nó đơn giản hóa giải pháp. Bằng cách này, độ dài của văn bản được giữ nguyên, do đó không cần theo dõi một chỉ mục riêng biệt.

public class InvalidXmlCharacterReplacingStreamReader : TextReader
{
    private StreamReader implementingStreamReader;
    private char replacementCharacter;

    public InvalidXmlCharacterReplacingStreamReader(Stream stream, char replacementCharacter)
    {
        implementingStreamReader = new StreamReader(stream);
        this.replacementCharacter = replacementCharacter;
    }

    public override void Close()
    {
        implementingStreamReader.Close();
    }

    public override ObjRef CreateObjRef(Type requestedType)
    {
        return implementingStreamReader.CreateObjRef(requestedType);
    }

    public void Dispose()
    {
        implementingStreamReader.Dispose();
    }

    public override bool Equals(object obj)
    {
        return implementingStreamReader.Equals(obj);
    }

    public override int GetHashCode()
    {
        return implementingStreamReader.GetHashCode();
    }

    public override object InitializeLifetimeService()
    {
        return implementingStreamReader.InitializeLifetimeService();
    }

    public override int Peek()
    {
        int ch = implementingStreamReader.Peek();
        if (ch != -1)
        {
            if (
                (ch < 0x0020 || ch > 0xD7FF) &&
                (ch < 0xE000 || ch > 0xFFFD) &&
                ch != 0x0009 &&
                ch != 0x000A &&
                ch != 0x000D
                )
            {
                return replacementCharacter;
            }
        }
        return ch;
    }

    public override int Read()
    {
        int ch = implementingStreamReader.Read();
        if (ch != -1)
        {
            if (
                (ch < 0x0020 || ch > 0xD7FF) &&
                (ch < 0xE000 || ch > 0xFFFD) &&
                ch != 0x0009 &&
                ch != 0x000A &&
                ch != 0x000D
                )
            {
                return replacementCharacter;
            }
        }
        return ch;
    }

    public override int Read(char[] buffer, int index, int count)
    {
        int readCount = implementingStreamReader.Read(buffer, index, count);
        for (int i = index; i < readCount+index; i++)
        {
            char ch = buffer[i];
            if (
                (ch < 0x0020 || ch > 0xD7FF) &&
                (ch < 0xE000 || ch > 0xFFFD) &&
                ch != 0x0009 &&
                ch != 0x000A &&
                ch != 0x000D
                )
            {
                buffer[i] = replacementCharacter;
            }
        }
        return readCount;
    }

    public override Task<int> ReadAsync(char[] buffer, int index, int count)
    {
        throw new NotImplementedException();
    }

    public override int ReadBlock(char[] buffer, int index, int count)
    {
        throw new NotImplementedException();
    }

    public override Task<int> ReadBlockAsync(char[] buffer, int index, int count)
    {
        throw new NotImplementedException();
    }

    public override string ReadLine()
    {
        throw new NotImplementedException();
    }

    public override Task<string> ReadLineAsync()
    {
        throw new NotImplementedException();
    }

    public override string ReadToEnd()
    {
        throw new NotImplementedException();
    }

    public override Task<string> ReadToEndAsync()
    {
        throw new NotImplementedException();
    }

    public override string ToString()
    {
        return implementingStreamReader.ToString();
    }
}

Cuối cùng, đây là ý tưởng đúng nhưng việc triển khai của bạn có thể KHÔ hơn.
Jodrell

@Jodrell: Đã thêm phiên bản KHÔ ở đây .
Neolisk

1
@Neolisk: Cảm ơn! Tôi có lẽ đã dọn dẹp này trước khi gửi bài nó :)
Ryan Adams

4

Phương pháp dựa trên Regex

public static string StripInvalidXmlCharacters(string str)
{
    var invalidXmlCharactersRegex = new Regex("[^\u0009\u000a\u000d\u0020-\ud7ff\ue000-\ufffd]|([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])");
    return invalidXmlCharactersRegex.Replace(str, "");

}

Xem bài đăng trên blog của tôi để biết thêm chi tiết


1
Điều này chậm hơn ~ 50 lần so với giải pháp của dnewcome trên máy của tôi.
adotout

2

Các giải pháp trên dường như là để loại bỏ các ký tự không hợp lệ trước khi chuyển đổi sang XML.

Sử dụng mã này để xóa các ký tự XML không hợp lệ khỏi một chuỗi XML. ví dụ. & x1A;

    public static string CleanInvalidXmlChars( string Xml, string XMLVersion )
    {
        string pattern = String.Empty;
        switch( XMLVersion )
        {
            case "1.0":
                pattern = @"&#x((10?|[2-F])FFF[EF]|FDD[0-9A-F]|7F|8[0-46-9A-F]9[0-9A-F]);";
                break;
            case "1.1":
                pattern = @"&#x((10?|[2-F])FFF[EF]|FDD[0-9A-F]|[19][0-9A-F]|7F|8[0-46-9A-F]|0?[1-8BCEF]);";
                break;
            default:
                throw new Exception( "Error: Invalid XML Version!" );
        }

        Regex regex = new Regex( pattern, RegexOptions.IgnoreCase );
        if( regex.IsMatch( Xml ) )
            Xml = regex.Replace( Xml, String.Empty );
        return Xml;
    }

http://balajiramesh.wordpress.com/2008/05/30/strip-illegal-xml-characters-based-on-w3c-standard/


1
-1 Câu trả lời này không giải quyết câu hỏi được hỏi, và trong mọi trường hợp là sai và gây hiểu lầm vì nó chỉ loại bỏ các Tham chiếu Thực thể Ký tự XML không hợp lệ, chứ không loại bỏ các ký tự XML không hợp lệ.
Daniel Cassidy

1

Câu trả lời được sửa đổi hoặc câu trả lời gốc của Neolisk ở trên .
Các thay đổi: của ký tự \ 0 được chuyển, quá trình xóa được thực hiện, thay vì thay thế. đồng thời, sử dụng phương thức XmlConvert.IsXmlChar (char)

    /// <summary>
    /// Replaces invalid Xml characters from input file, NOTE: if replacement character is \0, then invalid Xml character is removed, instead of 1-for-1 replacement
    /// </summary>
    public class InvalidXmlCharacterReplacingStreamReader : StreamReader
    {
        private readonly char _replacementCharacter;

        public InvalidXmlCharacterReplacingStreamReader(string fileName, char replacementCharacter)
            : base(fileName)
        {
            _replacementCharacter = replacementCharacter;
        }

        public override int Peek()
        {
            int ch = base.Peek();
            if (ch != -1 && IsInvalidChar(ch))
            {
                if ('\0' == _replacementCharacter)
                    return Peek(); // peek at the next one

                return _replacementCharacter;
            }
            return ch;
        }

        public override int Read()
        {
            int ch = base.Read();
            if (ch != -1 && IsInvalidChar(ch))
            {
                if ('\0' == _replacementCharacter)
                    return Read(); // read next one

                return _replacementCharacter;
            }
            return ch;
        }

        public override int Read(char[] buffer, int index, int count)
        {
            int readCount= 0, ch;

            for (int i = 0; i < count && (ch = Read()) != -1; i++)
            {
                readCount++;
                buffer[index + i] = (char)ch;
            }

            return readCount;
        }


        private static bool IsInvalidChar(int ch)
        {
            return !XmlConvert.IsXmlChar((char)ch);
        }
    }

1

Tôi đã tạo một phiên bản cập nhật nhẹ của câu trả lời của @ Neolisk , hỗ trợ các *Asyncchức năng và sử dụng XmlConvert.IsXmlCharchức năng .Net 4.0 .

public class InvalidXmlCharacterReplacingStreamReader : StreamReader
{
    private readonly char _replacementCharacter;

    public InvalidXmlCharacterReplacingStreamReader(string fileName, char replacementCharacter) : base(fileName)
    {
        _replacementCharacter = replacementCharacter;
    }

    public InvalidXmlCharacterReplacingStreamReader(Stream stream, char replacementCharacter) : base(stream)
    {
        _replacementCharacter = replacementCharacter;
    }

    public override int Peek()
    {
        var ch = base.Peek();
        if (ch != -1 && IsInvalidChar(ch))
        {
            return _replacementCharacter;
        }
        return ch;
    }

    public override int Read()
    {
        var ch = base.Read();
        if (ch != -1 && IsInvalidChar(ch))
        {
            return _replacementCharacter;
        }
        return ch;
    }

    public override int Read(char[] buffer, int index, int count)
    {
        var readCount = base.Read(buffer, index, count);
        ReplaceInBuffer(buffer, index, readCount);
        return readCount;
    }

    public override async Task<int> ReadAsync(char[] buffer, int index, int count)
    {
        var readCount = await base.ReadAsync(buffer, index, count).ConfigureAwait(false);
        ReplaceInBuffer(buffer, index, readCount);
        return readCount;
    }

    private void ReplaceInBuffer(char[] buffer, int index, int readCount)
    {
        for (var i = index; i < readCount + index; i++)
        {
            var ch = buffer[i];
            if (IsInvalidChar(ch))
            {
                buffer[i] = _replacementCharacter;
            }
        }
    }

    private static bool IsInvalidChar(int ch)
    {
        return IsInvalidChar((char)ch);
    }

    private static bool IsInvalidChar(char ch)
    {
        return !XmlConvert.IsXmlChar(ch);
    }
}

0

Sử dụng chức năng này để loại bỏ các ký tự xml không hợp lệ.

public static string CleanInvalidXmlChars(string text)   
{   
       string re = @"[^\x09\x0A\x0D\x20-\xD7FF\xE000-\xFFFD\x10000-x10FFFF]";   
       return Regex.Replace(text, re, "");   
} 

-1
private static String removeNonUtf8CompliantCharacters( final String inString ) {
    if (null == inString ) return null;
    byte[] byteArr = inString.getBytes();
    for ( int i=0; i < byteArr.length; i++ ) {
        byte ch= byteArr[i]; 
        // remove any characters outside the valid UTF-8 range as well as all control characters
        // except tabs and new lines
        if ( !( (ch > 31 && ch < 253 ) || ch == '\t' || ch == '\n' || ch == '\r') ) {
            byteArr[i]=' ';
        }
    }
    return new String( byteArr );
}

1
-1 Câu trả lời này gây hiểu lầm và sai vì nó loại bỏ các ký tự hợp lệ trong cả Unicode và XML.
Daniel Cassidy

-1

Bạn có thể chuyển các ký tự không phải UTF như sau:

string sFinalString  = "";
string hex = "";
foreach (char ch in UTFCHAR)
{
    int tmp = ch;
   if ((ch < 0x00FD && ch > 0x001F) || ch == '\t' || ch == '\n' || ch == '\r')
    {
    sFinalString  += ch;
    }
    else
    {  
      sFinalString  += "&#" + tmp+";";
    }
}

1
-1 Câu trả lời này sai vì nó tạo ra các tham chiếu thực thể ký tự XML không hợp lệ (ví dụ: &#1;không phải là một tham chiếu thực thể ký tự XML hợp lệ). Ngoài ra, nó gây hiểu lầm vì nó loại bỏ các ký tự hợp lệ trong cả Unicode và XML.
Daniel Cassidy

ya thats giải pháp đúng nhưng trên là vì nếu bạn muốn vượt qua xml hợp lệ trong tập tin xml, hơn nó sẽ làm việc hoặc bạn không thể vượt qua nhân vật xml hợp lệ trong tài liệu xml
Murari Kumar

Bạn không thể chuyển các ký tự XML không hợp lệ vào tài liệu XML cho dù bạn làm gì. Ví dụ: ký tự U+0001 START OF HEADINGkhông được phép trong tài liệu XML được định dạng tốt và ngay cả khi bạn cố gắng thoát khỏi nó &#1;, ký tự đó vẫn không được phép trong tài liệu XML được định dạng tốt.
Daniel Cassidy

-5

Hãy thử điều này cho PHP!

$goodUTF8 = iconv("utf-8", "utf-8//IGNORE", $badUTF8);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.