Các ký tự không hợp lệ trong XML là gì


229

Tôi đang làm việc với một số XML chứa các chuỗi như:

<node>This is a string</node>

Một số loại dây mà tôi đang đi đến các hạch sẽ có nhân vật thích &, #, $, v.v .:

<node>This is a string & so is this</node>

Điều này là không hợp lệ do &.

Tôi không thể quấn các chuỗi này trong CDATA vì chúng cần phải như vậy. Tôi đã cố gắng tìm kiếm một danh sách các ký tự không thể đặt trong các nút XML mà không có trong CDATA.

Ai đó có thể chỉ cho tôi theo hướng của một hoặc cung cấp cho tôi một danh sách các nhân vật bất hợp pháp?


4
Bất kỳ lý do hợp lệ cho việc không sử dụng CDATA?
Peter Perháč

1
Có, tôi đang chuyển chuỗi cho một CMS có tên Fatwire và nút có dữ liệu không thể có trong CDATA, tôi không chắc tại sao đó là cách Fatwire hoạt động :(
RailsSon

@Peter: Làm thế nào tôi có thể sử dụng CDATA trong trường hợp của mình? stackoverflow.com/questions/6906705/
Radek

Câu trả lời:


147

Các ký tự không hợp lệ là &, <>(cũng như "hoặc 'trong các thuộc tính).

Họ đang trốn thoát bằng thực thể XML , trong trường hợp này bạn muốn &amp;cho &.

Tuy nhiên, thực sự, bạn nên sử dụng một công cụ hoặc thư viện viết XML cho bạn và tóm tắt loại điều này cho bạn để bạn không phải lo lắng về nó.


82
Một số ký tự điều khiển cũng không được phép. Xem câu trả lời của tôi dưới đây.
heo

43
Thật ra điều đó không hoàn toàn đúng. Một số ký tự ascii thấp hơn cũng không hợp lệ. Nếu bạn cố gắng viết 0x03 vào tài liệu Xml, bạn thường gặp lỗi và nếu bạn quản lý để thoát đúng vào tài liệu XML, hầu hết người xem sẽ phàn nàn về ký tự không hợp lệ. Trường hợp cạnh nhưng nó xảy ra.
Rick Strahl

16
Câu trả lời này là hoàn toàn sai. Đây là ngoại lệ XML của tôi với ký tự không hợp lệ 0x12 'System.Xml.XmlException:' ', giá trị thập lục phân 0x12, là một ký tự không hợp lệ'
George

8
Nó cũng sai theo hướng khác; cũng như thiếu mọi nhân vật bất hợp pháp, các nhân vật mà họ tuyên bố là bất hợp pháp là hoàn toàn hợp pháp, mặc dù có ý nghĩa đặc biệt trong bối cảnh.
Jon Hanna

6
Trong XML 1.0 có nhiều ký tự không hợp lệ. Trong thực tế, ngay cả việc sử dụng một thực thể ký tự cho hầu hết các ký tự điều khiển sẽ gây ra lỗi khi phân tích cú pháp.
Thayne

218

OK, hãy tách câu hỏi của các nhân vật rằng:

  1. hoàn toàn không hợp lệ trong bất kỳ tài liệu XML nào.
  2. cần phải được trốn thoát

Câu trả lời được cung cấp bởi @dolmen trong " Các ký tự không hợp lệ trong XML " vẫn hợp lệ nhưng cần được cập nhật với đặc tả XML 1.1.

1. Ký tự không hợp lệ

Các ký tự được mô tả ở đây là tất cả các ký tự được phép chèn vào tài liệu XML.

1.1. Trong XML 1.0

Danh sách toàn cầu của các ký tự được phép là:

[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

Về cơ bản, các ký tự điều khiển và ký tự trong phạm vi Unicode không được phép. Điều này cũng có nghĩa là việc gọi ví dụ thực thể nhân vật &#x3;bị cấm.

1.2. Trong XML 1.1

Danh sách toàn cầu của các ký tự được phép là:

[2] Char ::= [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

[2a] RestrictedChar ::= [#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86-#x9F]

Bản sửa đổi khuyến nghị XML này đã mở rộng các ký tự được phép để các ký tự điều khiển được phép và tính đến một bản sửa đổi mới của tiêu chuẩn Unicode, nhưng những ký tự này vẫn không được phép: NUL (x00) , xFFFE , xFFFF ...

Tuy nhiên, việc sử dụng các ký tự điều khiển và ký tự Unicode không xác định là không được khuyến khích.

Cũng có thể nhận thấy rằng tất cả các trình phân tích cú pháp không phải lúc nào cũng tính đến điều này và các tài liệu XML có các ký tự điều khiển có thể bị từ chối.

2. Các ký tự cần được thoát (để có được một tài liệu được định dạng tốt):

Các <phải được thoát ra với một &lt;tổ chức nào, kể từ khi nó được giả định là sự khởi đầu của một thẻ.

Các &phải được thoát ra với một &amp;tổ chức nào, kể từ khi nó được giả định là bắt đầu một tham chiếu thực thể

Các >được kết thúc bằng &gt;thực thể. Nó không bắt buộc - nó phụ thuộc vào bối cảnh - nhưng nó được khuyến khích để thoát khỏi nó.

Các 'được kết thúc bằng một &apos;thực thể - bắt buộc trong các thuộc tính được định nghĩa trong dấu nháy đơn nhưng nó được khuyên phải luôn luôn thoát khỏi nó.

Các "được kết thúc bằng một &quot;thực thể - bắt buộc trong các thuộc tính được định nghĩa trong dấu ngoặc kép nhưng nó được khuyên phải luôn luôn thoát khỏi nó.


171

Danh sách các ký tự hợp lệ có trong đặc tả XML :

Char       ::=      #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]  /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

7
Bạn nên lưu ý rằng mặc dù chúng là các ký tự hợp pháp, & < > " 'phải được thoát trong các bối cảnh nhất định.
D.Shawley

7
"Pháp lý" trong ngữ cảnh này có nghĩa là các giá trị được giải mã cuối cùng của chúng là hợp pháp, không phải là chúng hợp pháp trong luồng. Như trên, một số giá trị pháp lý phải được thoát trong luồng.
SilverbackNet

Tôi có một vấn đề trong đó 0x1c là một nhân vật bất hợp pháp ... Tìm kiếm một khả năng trong java làm thế nào để tránh những điều này ....
basZero

Một cái nhìn tổng quan tuyệt vời về các ký tự hợp lệ và không thể tìm thấy ở đây validchar.com/d/xml10/xml10_namestart
Tiến sĩ Max Völkel

8
@xamde Danh sách đó rất hay, nhưng nó chỉ hiển thị các ký tự có thể được sử dụng để bắt đầu một phần tử XML. Vấn đề hiện tại là các ký tự nào là hợp lệ trong một tệp XML nói chung. Có một số nhân vật không được phép ở bất cứ đâu.
Jon Senchyna

59

Đây là mã C # để xóa các ký tự XML không hợp lệ khỏi chuỗi và trả về chuỗi hợp lệ mới.

public static string CleanInvalidXmlChars(string text) 
{ 
    // From xml spec valid chars: 
    // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]     
    // any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. 
    string re = @"[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]"; 
    return Regex.Replace(text, re, ""); 
}

6
Đối với Java, mẫu regex sẽ giống nhau. Và sau đó, bạn có thể sử dụng phương thức được gọi là thay thế trong Chuỗi lớp mong đợi một mẫu biểu thức chính quy làm tham số. Kiểm tra cái này: docs.oracle.com/javase/6/docs/api/java/lang/iêu
mathifonseca

2
Tôi có các ký tự không hợp lệ như vậy trong chuỗi của mình: SUSITARIMO D & # x5; L DARBO SUTARTIES Mã này không xóa & # x5; Vì vậy, tài liệu xml không thành công.
Dainius Kreivys

Tôi tin rằng bạn không thể đặt mẫu này vào hàm tạo regex .NET. Tôi không nghĩ rằng nó nhận ra \u10000\u10FFFFlà các ký tự đơn lẻ vì chúng yêu cầu hai chartrường hợp utf-16 mỗi ký tự và theo các tài liệu có thể không có nhiều hơn 4 chữ số. [\u10000-\u10FFFF]rất có thể phân tích cú pháp như [ \u1000, 0-\u10FF, F, F] đó là lạ nhìn nhưng quy phạm pháp luật.
GSerg


7

Ngoài câu trả lời của potame, nếu bạn muốn thoát bằng khối CDATA.

Nếu bạn đặt văn bản của mình trong một khối CDATA thì bạn không cần phải sử dụng lối thoát . Trong trường hợp đó, bạn có thể sử dụng tất cả các ký tự trong phạm vi sau :

biểu diễn đồ họa của các nhân vật có thể

Lưu ý: Trên hết, bạn không được phép sử dụng ]]>chuỗi ký tự. Bởi vì nó sẽ khớp với phần cuối của khối CDATA.

Nếu vẫn còn các ký tự không hợp lệ (ví dụ: các ký tự điều khiển), thì có lẽ tốt hơn là sử dụng một số loại mã hóa (ví dụ: base64).


3
Wether trong một khối CDATA hay không, một số ký tự bị cấm trong XML.
heo

4
chính xác, đó không phải là những gì tôi đã viết? trích dẫn: "tất cả các nhân vật trong phạm vi sau ". Ý tôi là, chỉ những nhân vật trong phạm vi cụ thể này. Các nhân vật khác không được phép. - hoàn toàn đồng ý; nhưng tôi không hiểu downvote. - mặc dù không có cảm giác khó khăn.
bvdb

6

Một cách dễ dàng khác để thoát các ký tự XML / XHTML có thể không mong muốn trong C # là:

WebUtility.HtmlEncode(stringWithStrangeChars)

Các ký tự không hợp lệ
dolmen

1
Anh viết Xml chứ không phải Html.
Emanuele

6

Một cách khác để loại bỏ các ký tự XML không chính xác trong C # đang sử dụng XmlConvert.IsXmlChar(Có sẵn từ .NET Framework 4.0)

public static string RemoveInvalidXmlChars(string content)
{
   return new string(content.Where(ch => System.Xml.XmlConvert.IsXmlChar(ch)).ToArray());
}

hoặc bạn có thể kiểm tra xem tất cả các ký tự có hợp lệ XML không:

public static bool CheckValidXmlChars(string content)
{
   return content.All(ch => System.Xml.XmlConvert.IsXmlChar(ch));
}

.Net Fiddle

Ví dụ: ký hiệu tab dọc ( \v) không hợp lệ đối với XML, nó là UTF-8 hợp lệ, nhưng XML 1.0 không hợp lệ và thậm chí nhiều thư viện (bao gồm libxml2) bỏ lỡ nó và âm thầm xuất ra XML không hợp lệ.


2

Tóm lại, các ký tự hợp lệ trong văn bản là:

  • tab, line-feed và vận chuyển trở lại.
  • tất cả các ký tự không kiểm soát là hợp lệ ngoại trừ &<.
  • >không hợp lệ nếu làm theo ]].

Phần 2.2 và 2.4 của đặc tả XML cung cấp câu trả lời chi tiết:

Nhân vật

Các ký tự pháp lý là tab, trả về vận chuyển, nguồn cấp dữ liệu và các ký tự pháp lý của Unicode và ISO / IEC 10646

Dữ liệu nhân vật

Ký tự dấu và (và) và dấu ngoặc góc trái (<) không được xuất hiện ở dạng nghĩa đen của chúng, ngoại trừ khi được sử dụng làm dấu phân cách đánh dấu hoặc trong một nhận xét, hướng dẫn xử lý hoặc phần CDATA. Nếu chúng cần ở nơi khác, chúng phải được thoát bằng cách sử dụng tham chiếu ký tự số hoặc chuỗi "&" và "<" tương ứng. Dấu ngoặc vuông (>) có thể được biểu diễn bằng chuỗi ">" và phải, để tương thích, phải được thoát bằng cách sử dụng ">" hoặc tham chiếu ký tự khi xuất hiện trong chuỗi "]]>" trong nội dung, khi đó xuất hiện trong chuỗi "]]>" trong nội dung, khi đó chuỗi không đánh dấu sự kết thúc của phần CDATA.



1
ampersand (&) is escaped to &amp;

double quotes (") are escaped to &quot;

single quotes (') are escaped to &apos; 

less than (<) is escaped to &lt; 

greater than (>) is escaped to &gt;

Trong C #, sử dụng System.Security.SecurityElement.Escapehoặc System.Net.WebUtility.HtmlEncodeđể thoát khỏi các ký tự bất hợp pháp này.

string xml = "<node>it's my \"node\" & i like it 0x12 x09 x0A  0x09 0x0A <node>";
string encodedXml1 = System.Security.SecurityElement.Escape(xml);
string encodedXml2= System.Net.WebUtility.HtmlEncode(xml);


encodedXml1
"&lt;node&gt;it&apos;s my &quot;node&quot; &amp; i like it 0x12 x09 x0A  0x09 0x0A &lt;node&gt;"

encodedXml2
"&lt;node&gt;it&#39;s my &quot;node&quot; &amp; i like it 0x12 x09 x0A  0x09 0x0A &lt;node&gt;"

1

Đối với người dùng Java, Apache có một lớp tiện ích ( StringEscapeUtils) có phương thức trợ giúp escapeXmlcó thể được sử dụng để thoát các ký tự trong chuỗi bằng các thực thể XML.


1

Trong bộ xử lý Woodstox XML, các ký tự không hợp lệ được phân loại theo mã này:

if (c == 0) {
    throw new IOException("Invalid null character in text to output");
}
if (c < ' ' || (c >= 0x7F && c <= 0x9F)) {
    String msg = "Invalid white space character (0x" + Integer.toHexString(c) + ") in text to output";
    if (mXml11) {
        msg += " (can only be output using character entity)";
    }
    throw new IOException(msg);
}
if (c > 0x10FFFF) {
    throw new IOException("Illegal unicode character point (0x" + Integer.toHexString(c) + ") to output; max is 0x10FFFF as per RFC");
}
/*
 * Surrogate pair in non-quotable (not text or attribute value) content, and non-unicode encoding (ISO-8859-x,
 * Ascii)?
 */
if (c >= SURR1_FIRST && c <= SURR2_LAST) {
    throw new IOException("Illegal surrogate pair -- can only be output via character entities, which are not allowed in this content");
}
throw new IOException("Invalid XML character (0x"+Integer.toHexString(c)+") in text to output");

Nguồn từ đây


-1

Bất cứ ai đã thử điều này System.Security.SecurityElement.Escape(yourstring)? Điều này sẽ thay thế các ký tự XML không hợp lệ trong một chuỗi bằng tương đương hợp lệ của chúng.


-5

Đối với XSL (vào những ngày thực sự lười biếng) tôi sử dụng:

capture="&amp;(?!amp;)" capturereplace="&amp;amp;"

để dịch tất cả các & không phù hợp với på amp; để những người thích hợp.

Chúng tôi có trường hợp đầu vào nằm trong CDATA nhưng hệ thống sử dụng XML không tính đến nó. Đó là một sửa chữa cẩu thả, hãy cẩn thận ...


8
Nếu nó cẩu thả, có thực sự cần thiết phải đăng nó ở đây?
heo
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.