it-swarm.dev

Neplatné znaky v XML

Momentálně pracuji s nějakým XML.

Mám uzly, které drží řetězce jako níže:

<node>This is a string</node>

Některé řetězce, které přecházím na uzly, budou mít znaky jako &, #, $ atd.

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

Toto neplatí z důvodu

Nemohu zabalit tyto řetězce do CDATA, protože musí být takové, jaké jsou. Snažil jsem se vyhledat online seznam znaků, které nelze vložit do XML uzlů, aniž by byly v CDATA.

Mohl by mě někdo namířit ve směru jednoho nebo mi poskytnout seznam nelegálních postav?

188
RailsSon

Jediné nelegální znaky jsou &, < a > (stejně jako " nebo ' v atributech).

Jsou unikány pomocí XML ​​entit , v tomto případě chcete &amp; pro &.

Opravdu, měli byste však použít nástroj nebo knihovnu, která pro vás zapisuje XML a abstrahuje tento druh věci pro vás, takže se o to nemusíte starat.

127
Welbog

OK, pojďme oddělit otázku (1) znaků, které nejsou platné v žádném dokumentu XML, a (2) znaků, které je třeba uniknout:

Odpověď poskytovaná @dolmen Neplatné znaky v XML je stále platná, ale musí být aktualizována specifikací XML 1.1.

1. Neplatné znaky

Zde popsané znaky jsou všechny znaky, které mohou být vloženy do dokumentu XML.

1.1. V XML 1.0

Celkový seznam povolených znaků je:

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

Řídicí znaky a znaky mimo rozsahy Unicode nejsou v zásadě povoleny. To také znamená, že volání například znakové entity &#x3; je zakázáno.

1.2. V XML 1.1

Celkový seznam povolených znaků je:

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

Tato revize doporučení XML rozšířila povolené znaky, takže jsou povoleny kontrolní znaky a bere v úvahu novou revizi standardu Unicode, ale tyto nejsou stále povoleny: NUL (x00), xFFFE, xFFFF ...

Použití řídicích znaků a nedefinovaného znaku Unicode je však odrazováno.

Je také možné si všimnout, že všechny analyzátory to neberou vždy v úvahu a XML dokumenty s kontrolními znaky mohou být odmítnuty.

2. Znaky, které je třeba uniknout (pro získání dobře vytvořeného dokumentu):

Soubor < musí být vynechán entitou &lt;, protože se předpokládá, že se jedná o začátek značky.

Soubor & musí být vynechán entitou &amp;, protože se předpokládá, že je to začátek reference entity

> by mělo být vynecháno pomocí &gt; entity. Není to povinné - záleží na kontextu - ale důrazně se doporučuje uniknout.

Soubor ' by měl být vynechán entitou &apos; - povinná v atributech definovaných v rámci jednoduchých uvozovek, ale důrazně se doporučuje vždy uniknout.

Soubor " by měl být vynechán entitou &quot; - povinná v atributech definovaných v uvozovkách, ale důrazně se doporučuje vždy uniknout.

174
potame

Seznam platných znaků je ve specifikaci XML ​​ :

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

Toto je kód C #, který odstraní neplatné znaky XML z řetězce a vrátí nový platný řetězec.

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, ""); 
}
55
mathifonseca

Předem označené znaky jsou:

& < > " '

http://xml.silmaril.ie/specials.html

17
cgp

Další snadný způsob, jak uniknout potenciálně nechtěným XML/XHTML znakům v C # je:

WebUtility.HtmlEncode(stringWithStrangeChars)
7
tiands

Kromě potame je odpověď, pokud chcete uniknout pomocí bloku CDATA.

Pokud vložíte text do bloku CDATA, nemusíte používat escaping. V tomto případě můžete použít všechny znaky v následujícím rozsahu:

 graphical representation of possible characters

Poznámka: Kromě toho není dovoleno používat posloupnost znaků ]]>. Protože by odpovídala konci bloku CDATA.

Pokud stále existují neplatné znaky (např. Kontrolní znaky), pak je pravděpodobně lepší použít nějaký druh kódování (např. Base64).

4
bvdb

Tato odpověď pracovala pro mě

string code = Regex.Replace(item.Code, @"[\u0000-\u0008,\u000B,\u000C,\u000E-\u001F]", "");

Podrobnosti v tomto odkazu na blog

2
Kalpesh Popat

Další způsob, jak odstranit nesprávné znaky XML v jazyce C # pomocí Metoda XmlConvert.IsXmlChar (K dispozici od .NET Framework 4.0)

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

nebo můžete zkontrolovat, zda jsou všechny znaky platné ve formátu XML.

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

.Net Fiddle - https://dotnetfiddle.net/v1TNus

Například symbol svislé karty (v) není platný pro XML, je platný UTF-8, ale není platný XML 1.0, a dokonce i mnoho knihoven (včetně libxml2) chybí a tichý výstup XML chybí.

2
Alex Vazhev

V procesoru Woodstox XML jsou neplatné znaky klasifikovány tímto kódem

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

Zdroj z zde

1

Pro lidi v jazyce Java má Apache třídu nástrojů (StringEscapeUtils), která má pomocnou metodu escapeXml, kterou lze použít k úniku znaků v řetězci pomocí entit XML.

1
A Null Pointer

Souhrnně platí, že platné znaky v textu jsou:

  • karta, posun řádku a návrat vozíku;
  • všechny nekontrolní znaky jsou platné kromě & a <;
  • > není platný, pokud následuje]].

Oddíly 2.2 a 2.4 specifikace XML poskytují podrobnou odpověď:

Znaky

Právní znaky jsou karta, návrat vozíku, posun řádku a právní znaky Unicode a ISO/IEC 10646

Data znaků

Znak ampersand (&) a levý úhel závorky (<) nesmí Být zobrazeny v jejich doslovné podobě, kromě případů, kdy jsou použity jako oddělovače značek, Nebo v komentáři, instrukci zpracování nebo Sekce CDATA. Pokud je Potřeba jinde, musí být uniknuty pomocí číselných odkazů Nebo řetězců "&" a "<" . Pravoúhlá závorka (>) může být reprezentována pomocí řetězce ">" A pro kompatibilitu musí být vynechána pomocí buď ">" Nebo odkazu na znak, když se objeví v řetězci "]]> " v obsahu, pokud tento řetězec neoznačuje konec oddílu CDATA .

0
rghome
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;

V C # použijte System.Security.SecurityElement.Escape nebo System.Net.WebUtility.HtmlEncode k úniku těchto nelegálních znaků.

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;"
0
live-love

Tento soubor System.Security.SecurityElement.Escape(yourstring)?

0
klaydze