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?
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 " here, ' is allowed"
i attr='must use ' here, " is allowed'
).
Są one unikane przy użyciuencji XML , w tym przypadku chcesz &
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ć.
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:
- nie są w ogóle ważne w żadnym dokumencie XML.
- 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
- odniesienie: patrz zalecenie XML 1.0, §2.2 znaki
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 
jest zabronione.
1.2. W XML 1.1
- odniesienie: patrz zalecenie XML 1.1, §2.2 znaki i 1.3 uzasadnienie i lista zmian dla 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ą <
, 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 >
byt. Nie jest to obowiązkowe-zależy to od kontekstu - ale zdecydowanie zaleca się od niego uciec.
'
powinien być zabezpieczony encją '
-- obowiązkową w atrybutach zdefiniowanych w pojedynczych cudzysłowach, ale zaleca się, aby zawsze go chronić.
"
powinien być zabezpieczony "
encją -- obowiązkową w atrybutach zdefiniowany w cudzysłowach podwójnych, ale zaleca się, aby zawsze z nich uciekać.
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. */
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, "");
}
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.
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 :
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).
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));
}
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.
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)
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.
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]", "");
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 &
double quotes (") are escaped to "
single quotes (') are escaped to '
less than (<) is escaped to <
greater than (>) is escaped to >
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
"<node>it's my "node" & i like it 0x12 x09 x0A 0x09 0x0A <node>"
encodedXml2
"<node>it's my "node" & i like it 0x12 x09 x0A 0x09 0x0A <node>"
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.
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
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.
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;)" capturereplace="&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...
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