2011-01-24 34 views
7

Ho una stringa con dati xml che ho estratto da un servizio web. I dati sono brutti e presentano caratteri non validi nei tag Name di xml. Ad esempio, potrei vedere qualcosa del tipo:Rimozione caratteri non validi dal tag nome XML - RegEx C#

<Author>Scott the Coder</Author><Address#>My address</Address#> 

Il # nel campo Nome indirizzo non è valido. Sto cercando un'espressione regolare che rimuova tutti i caratteri non validi dalle etichette del nome MA lascia tutti i caratteri nella sezione Valore del xml. In altre parole, voglio usare RegEx per rimuovere i char solo dai tag dei nomi di apertura e dai tag di chiusura dei nomi. Tutto il resto dovrebbe rimodellare lo stesso.

Non ho tutti i caratteri non validi ancora, ma questo sarà fatemi parlare: # {} &()

E 'possibile fare quello che sto cercando di fare?

+2

È consigliabile evitare di fare riferimento a "Dati XML". Non è XML. Ecco perché hai problemi con questo. Devi rendere il fornitore dei dati consapevole che il loro output è spazzatura. –

+1

Ya, questo è quello che devo fare. Non c'è motivo di provare e semplificare le cose su questa bacheca mentre si risolve un problema. Dovrei dare la caccia al ragazzo che l'ha fatto e dirgli che è un cattivo ragazzo. Questo risolverà il mio problema .... ehm, aspetta, no ... ho ancora lo stesso problema ... Avanti! – Scott

+0

Si potrebbe voler aggiungere '$' ai caratteri non consentiti. – TinyTimZamboni

risposta

1

Avevo un modulo semplice con due aree di testo e un pulsante. Questo sembra fare il trucco.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Text.RegularExpressions; 

namespace WindowsFormsApplication3 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Regex r = new Regex(@"(?<=\<\w+)[#\{\}\(\)\&](?=\>)|(?<=\</\w+)[#\{\}\(\)\&](?=\>)"); 
      textBox2.Text = r.Replace(textBox1.Text, new MatchEvaluator(deleteMatch)); 
     } 

     string deleteMatch(Match m) { return ""; } 
    } 
} 
+0

Sto cercando di evitare di cercare la stringa più di una volta poiché la stringa potrebbe essere enorme. Tuttavia, se non riesco a trovare un modo RegEx pulito per farlo, dovrò passare un po 'di tempo a scrivere un parser che faccia proprio questo. – Scott

+0

Capisco meglio ora. Questo sembra qualcosa che potrebbe aiutare: http://www.perlmonks.org/?node_id=518444 (voglio dire guardare avanti e guardare dietro, non la parte perl). Ok li ho trovati per C# regexp: (? = ...) \t Un lookahead positivo (?! ...) \t Un lookahead negativo (? <= ...) \t Un look positivo. (? Marco

1

RegEx è un modo problematico per andare a meno che non hai davvero solo un file da elaborare. Il dolore, la frustrazione, bug è il vostro futuro c'è ...

vi davvero desidera utilizzare un RegEx, ci sono quelli utili HERE che ho utilizzato in Perl.

Hai mai pensato di utilizzare un parser?

Due da considerare:

LINQ for XML

XmlDocument

Una volta analizzato, è possibile ri-salvare le sezioni molesti o semplicemente andare sul vostro modo programmatico.

+0

Non sono sicuro che questi caratteri siano validi o meno per i nomi dei tag, ma se non lo sono potreste non essere in grado di analizzare l'xml (infatti, potrebbe essere ciò che ha portato a questa domanda). Se puoi analizzarlo, non devi risolverlo. Vale la pena provare con parser diversi pensato. – Kobi

+0

In realtà, XMLDocument è il mio problema. XMLDocument genera quando xmlDoc.LoadXml (xmlString). Ho bisogno di ripararlo prima di eseguirlo attraverso il parser. A meno che non ci sia qualcosa su XMLDocument che non conosco, non lo uso in questo modo ?? – Scott

+0

@Kobi Tutti questi caratteri non sono validi nei nomi degli elementi. Nessun parser XML conforme accetterà questo input. –

5

Se l'intenzione è di controllare solo la validità di un nome per un nodo Xml, suggerisco di dare un'occhiata alla classe XmlConvert; in particolare i metodi VerifyName e VerifyNCName.

Si noti inoltre che con quella classe è possibile accettare qualsiasi testo come nome nodo utilizzando i metodi EncodeName e EncodeLocalName.

L'utilizzo di questi metodi sarà molto più semplice, sicuro e più veloce rispetto all'esecuzione di un'espressione regolare.

+1

Si noti che i metodi Verifica * Nome generano un'eccezione che sarebbe un successo. – hcoverlambda

1

Prova questo:

s = Regex.Replace(s, @"[#{}&()]+(?=[^<>]*>)", ""); 

Se il lookahead riesce, la prossima squadretta dopo la partita è una rivolta a destra uno (>), che indica che la partita si è verificato all'interno di un tag.

Ovviamente, questo presuppone che il testo sia ragionevolmente ben formato e che non contenga parentesi angolari oltre a quelle nei tag.

1

è possibile utilizzare la stringa sostituita per sostituire tutti i caratteri non validi. Solitamente i caratteri di controllo ascii creano problemi nella lettura XML.

per evitare l'uso di questa funzione

 public static string CleanInvalidXmlChars(this 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-\xD7FF\xE000-\xFFFD\x10000-x10FFFF]"; 
     return Regex.Replace(text, re, ""); 
    } 


    xmlcontent = xmlcontent.CleanInvalidXmlChars(); 

questo pulirà chracters specificate nell'espressione regolare. i get this from this site

+0

Penso che questa espressione regolare manchi "\" prima di "x10FFFF". Ad esempio, non eliminerà \ x10 –

Problemi correlati