Wat zijn ongeldige tekens in XML

Ik werk met een XML die strings bevat zoals:

<node>This is a string</node>

Sommige van de tekenreeksen die ik doorgeef aan de knooppunten, hebben tekens zoals &, #, $, enz.:

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

Dit is niet geldig vanwege &.

Ik kan deze strings niet in CDATA verpakken omdat ze moeten zijn zoals ze zijn. Ik heb geprobeerd te zoeken naar een lijst met tekens die niet in XML-knooppunten kunnen worden geplaatst zonder in een CDATA te staan.

Kan iemand me in de richting van een van die tekens wijzen of me een lijst met illegale tekens geven?


Antwoord 1, autoriteit 100%

De enige illegale tekens zijn &, <en >(evenals "of 'in attributen, afhankelijk van welk teken wordt gebruikt om de attribuutwaarde af te bakenen: attr="must use &quot; here, ' is allowed"en attr='must use &apos; here, " is allowed').

Ze zijn ontsnapt met behulp van XML-entiteiten, in dit geval wil je &amp;voor &.

Eigenlijk zou u echter een tool of bibliotheek moeten gebruiken die XML voor u schrijft en dit soort dingen voor u abstraheert, zodat u zich er geen zorgen over hoeft te maken.


Antwoord 2, autoriteit 95%

OK, laten we de vraag scheiden van de tekens die:

  1. zijn helemaal niet geldig in een XML-document.
  2. moeten ontsnappen.

Het antwoord van @dolmen in “Wat zijn ongeldige tekens in XML” is nog steeds geldig, maar moet worden bijgewerkt met de XML 1.1-specificatie.

1. Ongeldige tekens

De hier beschreven tekens zijn alle tekens die in een XML-document mogen worden ingevoegd.

1.1. In XML 1.0

De algemene lijst met toegestane tekens is:

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

In principe zijn de controletekens en tekens uit de Unicode-reeksen niet toegestaan.
Dit betekent ook dat het aanroepen van bijvoorbeeld de karakterentiteit &#x3;verboden is.

1.2. In XML 1.1

De algemene lijst met toegestane tekens is:

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

Deze herziening van de XML-aanbeveling heeft de toegestane tekens uitgebreid, zodat controletekens zijn toegestaan, en houdt rekening met een nieuwe herziening van de Unicode-standaard, maar deze zijn nog steeds niet toegestaan: NUL (x00), xFFFE, xFFFF

Het gebruik van controletekens en ongedefinieerde Unicode-tekens wordt echter afgeraden.

Ook kan worden opgemerkt dat niet alle parsers hier altijd rekening mee houden en XML-documenten met controletekens kunnen worden afgewezen.

2. Tekens die moeten worden ontsnapt (om een goed gevormd document te verkrijgen):

De <moet worden geëscaped met een &lt;entiteit, aangezien wordt aangenomen dat dit het begin van een tag is.

De &moet worden geëscaped met een &amp;entiteit, aangezien wordt aangenomen dat dit het begin is van een entiteitsverwijzing

De >moet worden geëscaped met de entiteit &gt;. Het is niet verplicht — het hangt af van de context — maar het wordt sterk aangeraden om eraan te ontsnappen.

De 'moet worden geëscaped met een &apos;entiteit — verplicht in attributen gedefinieerd tussen enkele aanhalingstekens, maar het wordt sterk aangeraden om er altijd aan te ontsnappen.

p>

De "moet worden geëscaped met een &quot;entiteit — verplicht in attributen gedefinieerd tussen dubbele aanhalingstekens, maar het wordt sterk aangeraden om er altijd aan te ontsnappen.

p>


Antwoord 3, autoriteit 92%

De lijst met geldige tekens staat in de XML-specificatie:

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

Antwoord 4, autoriteit 37%

Dit is een C#-code om de ongeldige XML-tekens uit een tekenreeks te verwijderen en een nieuwe geldige tekenreeks te retourneren.

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

Antwoord 5, autoriteit 10%

De vooraf aangegeven tekens zijn:

& < > " '

Zie “Wat zijn de speciale tekens in XML?” voor meer informatie.

p>


Antwoord 6, autoriteit 7%

Naast het antwoord van potame, als je wilt ontsnappen met een CDATA-blok.

Als u uw tekst in een CDATA-blok plaatst, hoeft u geen escaping te gebruiken.
In dat geval kunt u alle tekens in het volgende bereikgebruiken:

Opmerking: bovendien mag u de tekenreeks ]]>niet gebruiken. Omdat het overeenkomt met het einde van het CDATA-blok.

Als er nog steeds ongeldige tekens zijn (bijv. controletekens), is het waarschijnlijk beter om een soort codering te gebruiken (bijv. base64).


Antwoord 7, autoriteit 4%

Nog een manier om onjuiste XML-tekens in C # te verwijderen, gebruikt XmlConvert.IsXmlChar(beschikbaar sinds .NET Framework 4.0)

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

of u kunt controleren of alle tekens XML-geldig zijn:

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

.NET fiddle

Het verticale tabsymbool (\v) is bijvoorbeeld niet geldig voor XML, het is geldig UTF-8, maar niet geldig XML 1.0, en zelfs veel bibliotheken (inclusief libxml2) en stilletjes ongeldige XML uitgang.


8, Autoriteit 4%

Nog een eenvoudige manier om te ontsnappen Potentieel ongewenste XML / XHTML-tekens in C # is:

WebUtility.HtmlEncode(stringWithStrangeChars)

Antwoord 9

Voor Java-mensen heeft Apache een hulpprogrammaklasse (StringEscapeUtils) die een helpermethode escapeXmlheeft die kan worden gebruikt voor escapetekens in een tekenreeks met behulp van XML-entiteiten.


Antwoord 10

XmlWriter en lagere ASCII tekens” werkte voor mij

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

Antwoord 11

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;

Gebruik in C# System.Security.SecurityElement.Escapeof System.Net.WebUtility.HtmlEncodeom aan deze illegale tekens te ontsnappen.

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

Antwoord 12

In de Woodstox XML-processor worden ongeldige tekens geclassificeerd door deze code:

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

Bron van hier


Antwoord 13

Iedereen heeft dit System.Security.SecurityElement.Escape(yourstring)geprobeerd?
Hiermee worden ongeldige XML-tekens in een tekenreeks vervangen door hun geldige equivalent.


Antwoord 14

Voor XSL (op echt luie dagen) gebruik ik:

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

om alle &-tekens te vertalen die niet worden gevolgd på amp; naar de juiste.

We hebben gevallen waarin de invoer in CDATA is, maar het systeem dat de XML gebruikt, houdt er geen rekening mee. Het is een slordige oplossing, pas op…

Other episodes