Co to są nieprawidłowe znaki w XML

Pracuję z jakimś XML, który zawiera łańcuchy takie jak:

<node>This is a string</node>

Niektóre z łańcuchów, które przekazuję do węzłów, będą miały znaki takie jak &, #, $, itd.:

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

Nie jest to ważne ze względu na &.

Nie mogę zawinąć tych ciągów w CDATA tak, jak muszą być takie, jakie są. Próbowałem szukać listy znaków, których nie można umieścić w węzłach XML bez bycia w CDATA.

Czy ktoś może wskazać mi kierunek jednego lub podać mi z listą nielegalnych postaci?

 246
xml
Author: the Tin Man, 2009-04-08

15 answers

Jedynymi nielegalnymi znakami są &, < i > (a także " lub ' w atrybutach, w zależności od tego, który znak jest używany do rozgraniczenia wartości atrybutu: attr="must use &quot; here, ' is allowed" i attr='must use &apos; here, " is allowed').

Są one unikane przy użyciuencji XML , w tym przypadku chcesz &amp; dla &.

Naprawdę powinieneś użyć narzędzia lub biblioteki, która pisze XML dla Ciebie i abstrakcji tego rodzaju rzeczy dla ciebie, więc nie musisz się o to martwić.

 154
Author: Welbog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-12 15:17:10

OK, rozdzielmy pytanie o znaki, które:

  1. nie są w ogóle ważne w żadnym dokumencie XML.
  2. trzeba uciec.

Odpowiedź udzielona przez @dolmen w " jakie są nieprawidłowe znaki w XML " jest nadal ważna, ale musi być zaktualizowana o specyfikację XML 1.1.

1. Invalid characters

Opisane tutaj znaki to wszystkie znaki, które mogą być wstawiane do XML dokument.

1.1. W XML 1.0

Globalna lista dozwolonych znaków to:

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

Zasadniczo znaki sterujące i znaki spoza zakresu Unicode nie są dozwolone. Oznacza to również, że wywołanie na przykład encji znakowej &#x3; jest zabronione.

1.2. W XML 1.1

Globalna lista dozwolonych znaków to:

[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]

Ta zmiana zalecenia XML rozszerzyła dozwolone znaki, więc znaki kontrolne są dozwolone i uwzględnia nową rewizję standardu Unicode, ale te nadal nie są dozwolone : NUL (x00), xFFFE , xFFFF ...

Nie zaleca się jednak używania znaków sterujących i niezdefiniowanego znaku Unicode.

Można również zauważyć, że wszystkie parsery nie zawsze biorą to pod uwagę i dokumenty XML ze znakami kontrolnymi mogą zostać odrzucone.

2. Znaki, które muszą zostać usunięte (aby uzyskać dobrze uformowany dokument):

< musi być zabezpieczony encją &lt;, ponieważ zakłada się, że jest to początek znacznika.

& musi być w przeciwieństwie do innych języków, w których nie ma żadnego znaczenia.]}

> powinien być unikany przez &gt; byt. Nie jest to obowiązkowe-zależy to od kontekstu - ale zdecydowanie zaleca się od niego uciec.

' powinien być zabezpieczony encją &apos; -- obowiązkową w atrybutach zdefiniowanych w pojedynczych cudzysłowach, ale zaleca się, aby zawsze go chronić.

" powinien być zabezpieczony &quot; encją -- obowiązkową w atrybutach zdefiniowany w cudzysłowach podwójnych, ale zaleca się, aby zawsze z nich uciekać.

 244
Author: potame,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-07 03:43:21

Lista ważnych znaków znajduje się w specyfikacji XML :

Char       ::=      #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]  /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */
 173
Author: dolmen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-24 20:34:52

Jest to kod C#, który usuwa nieprawidłowe znaki XML z łańcucha i zwraca nowy prawidłowy łańcuch.

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, ""); 
}
 59
Author: mathifonseca,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-23 20:19:53

Znaki poprzedzające to:

& < > " '

Zobacz " Jakie są znaki specjalne w XML? " aby uzyskać więcej informacji.

 17
Author: cgp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-07 03:44:48

Oprócz odpowiedzi potame, jeśli chcesz uciec za pomocą bloku CDATA.

Jeśli umieścisz swój tekst w bloku CDATA, nie musisz używać ucieczki. W takim przypadku możesz użyć wszystkich znaków w następującym zakresie :

graficzna reprezentacja możliwych znaków

Uwaga: poza tym nie wolno używać sekwencji znaków ]]>. Ponieważ pasowałby do końca bloku CDATA.

Jeśli nadal istnieją nieprawidłowe znaki (np. znaki sterujące), wtedy chyba lepiej użyć jakiegoś kodowania (np. base64).

 10
Author: bvdb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-01 14:55:57

Innym sposobem na usunięcie nieprawidłowych znaków XML w C# jest użycie XmlConvert.IsXmlChar (Dostępne od. NET Framework 4.0)

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

Lub możesz sprawdzić, czy wszystkie znaki są XML-valid:

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

. Net

Na przykład symbol pionowej zakładki (\v) nie jest poprawny dla XML, jest poprawny UTF-8, ale nie poprawny XML 1.0, a nawet wiele bibliotek (w tym libxml2) go pomija i po cichu wypisuje nieprawidłowy XML.

 7
Author: Alex Vazhev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-07 03:51:53

Innym łatwym sposobem na uniknięcie potencjalnie niechcianych znaków XML / XHTML w C# jest:

WebUtility.HtmlEncode(stringWithStrangeChars)
 6
Author: tiands,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-19 10:01:02

W podsumowaniu ważne znaki w tekście to:

  • tab, line-feed i carriage-return.
  • Wszystkie znaki niekanoniczne są ważne z wyjątkiem & i <.
  • {[2] } nie jest ważne, jeśli następuje ]].

Sekcje 2.2 i 2.4 specyfikacji XML dostarczają szczegółowej odpowiedzi:

Znaki

Znaki prawne to tabulator, powrót karetki, kanał linii oraz znaki prawne Unicode i ISO / IEC 10646

Dane znakowe

Znak ampersand ( & ) i lewy nawias kątowy ( ) można przedstawić za pomocą string " > ", i musi, dla kompatybilności, Być unikane za pomocą albo ">"lub odniesienie do znaku, gdy pojawia się w łańcuchu"]] > "w treści, gdy ciąg ten nie oznacza końca CDATA sekcja.

 2
Author: rghome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-07 03:47:30

"XmlWriter i niższe znaki ASCII" działało dla mnie

string code = Regex.Replace(item.Code, @"[\u0000-\u0008,\u000B,\u000C,\u000E-\u001F]", "");
 2
Author: Kalpesh Popat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-07 03:49:57
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;

W C# użyj System.Security.SecurityElement.Escape lub System.Net.WebUtility.HtmlEncode, aby uciec od tych nielegalnych znaków.

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
Author: live-love,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-07 03:46:07

Dla ludzi Javy, Apache ma klasę narzędzi (StringEscapeUtils), która ma metodę pomocniczą escapeXml, która może być używana do znaków specjalnych w łańcuchu za pomocą encji XML.

 1
Author: A Null Pointer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-07 03:48:18

W procesorze Woodstox XML nieprawidłowe znaki są klasyfikowane za pomocą tego kodu:

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");

Źródło z tutaj

 1
Author: Jerome Saint-Yves,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-07 03:48:44

Ktoś próbował tego System.Security.SecurityElement.Escape(yourstring)? Spowoduje to zastąpienie nieprawidłowych znaków XML w łańcuchu znaków ich poprawnym odpowiednikiem.

 -1
Author: klaydze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-07 03:46:30

Do XSL (w naprawdę leniwe dni) używam:

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

Aby przetłumaczyć wszystkie &-znaki, które nie są follwed på amp; na właściwe.

Mamy przypadki, w których dane wejściowe są w CDATA, ale system, który używa XML, nie bierze tego pod uwagę. To niechlujne rozwiązanie, uważaj...

 -5
Author: Samson Wiklund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-17 15:36:03