2011-01-24 18 views
7

Tengo una cadena con datos xml que extraje de un servicio web. La información es fea y tiene algunos caracteres no válidos en las etiquetas de Nombre del xml. Por ejemplo, es posible que vea algo como:Eliminación de caracteres no válidos de la etiqueta de nombre XML - RegEx C#

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

El n. ° en el campo Nombre de dirección no es válido. Estoy buscando una expresión regular que elimine todos los caracteres no válidos de las etiquetas de nombre, PERO deje todos los caracteres en la sección Valor del xml. En otras palabras, quiero usar RegEx para eliminar caracteres solo de las etiquetas de nombre de apertura y las etiquetas de nombre de cierre. Todo lo demás debería seguir igual.

que no tienen todos los caracteres no válidos todavía, pero esto va a ayudarme a empezar: # {} &()

¿Es posible hacer lo que yo estoy tratando de hacer?

+2

Es una buena idea evitar referirse a cosas como "datos XML". No es XML. Es por eso que estás teniendo problemas con eso. Debe informar al proveedor de los datos que su salida es basura. –

+1

Ya, eso es lo que tengo que hacer. No hay razón para intentar y simplificar las cosas en este tablero de mensajes mientras se resuelve un problema. Solo debería perseguir al tipo que lo hizo y decirle que es un chico malo. Eso resolverá mi problema ... eh, espera, no ... todavía tengo el mismo problema ... ¡Siguiente! – Scott

+0

Es posible que desee agregar '$' a los caracteres no permitidos. – TinyTimZamboni

Respuesta

1

Tenía un formulario simple con dos áreas de texto y un botón. Esto parece hacer el truco.

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

Estoy tratando de evitar buscar la cadena más de una vez ya que la cadena podría ser enorme. Sin embargo, si no puedo encontrar una forma limpia de RegEx para hacerlo, tendré que dedicar algo de tiempo a escribir un analizador sintáctico que haga precisamente eso. – Scott

+0

Lo entiendo mejor ahora. Esto parece ser algo que ayudaría: http://www.perlmonks.org/?node_id=518444 (me refiero a mirar hacia adelante y mirar hacia atrás, no la parte perl). Ok, los encontré para C# regexp: (? = ...) \t Un positivo lookahead (?! ...) \t Un lookahead negativo (? <= ...) \t Una mirada positiva detrás. (? Marco

1

RegEx es una forma problemática de proceder a menos que realmente solo tenga que procesar un archivo. El dolor, la frustración, los insectos es su futuro allí ...

Te realmente desea utilizar una expresión regular, no son los útiles HERE que he utilizado en Perl.

¿Ha considerado utilizar un analizador en su lugar?

dos a considerar:

LINQ for XML

XmlDocument

Una vez analizado sintácticamente, se puede volver a guardar las secciones molestos o simplemente ir en su manera programática.

+0

No estoy seguro de si estos caracteres son válidos para nombres de etiquetas o no, pero si no lo son, es posible que no pueda analizar el xml (de hecho, eso puede ser lo que llevó a esta pregunta). Si puedes analizarlo, realmente no tienes que arreglarlo. Vale la pena intentarlo con diferentes analizadores pensados. – Kobi

+0

En realidad, XMLDocument es donde está mi problema. XMLDocument lanza cuando xmlDoc.LoadXml (xmlString). Necesito arreglarlo antes de ejecutarlo a través del analizador. A menos que haya algo sobre XMLDocument que no conozca, no puedo usarlo de esta manera? – Scott

+0

@Kobi Todos estos caracteres no son válidos en los nombres de elementos. Ningún analizador XML conforme aceptará esta entrada. –

5

Si su intención es verificar únicamente la validez de un nombre para un nodo Xml, le sugiero que eche un vistazo a la clase XmlConvert; especialmente los métodos VerifyName y VerifyNCName.

También tenga en cuenta que con esa clase, podría aceptar cualquier texto como nombre de nodo utilizando los métodos EncodeName y EncodeLocalName.

Usar estos métodos será mucho más fácil, seguro y más rápido que realizar una expresión regular.

+1

Tenga en cuenta que los métodos Verify * Name arrojan una excepción que sería un golpe de percusión. – hcoverlambda

1

Prueba esto:

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

Si la búsqueda hacia delante tiene éxito, el siguiente soporte en ángulo tras el partido es un derecho que apunta uno (>), lo que indica que el partido se produjo dentro de una etiqueta.

Por supuesto, esto supone que el texto está razonablemente bien formado y que no contiene corchetes angulares aparte de los de las etiquetas.

1

puede reemplazar cadenas para reemplazar todos los caracteres inválidos. Normalmente, los caracteres de control ascii crearán problemas en la lectura de XML.

para evitar el uso de esta función

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

esto va a limpiar chracters especificados en la expresión regular. i get this from this site

+0

Creo que esta expresión regular falta "\" antes de "x10FFFF". No se quitará \ x10 por ejemplo –

Cuestiones relacionadas