Estoy buscando la solución limpia, elegante e inteligente para eliminar los espacios de nombres de todos los elementos XML. ¿Cómo funcionaría para hacer eso?
Interfaz definida:
public interface IXMLUtils
{
string RemoveAllNamespaces(string xmlDocument);
}
XML de muestra para eliminar NS de:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfInserts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<insert>
<offer xmlns="http://schema.peters.com/doc_353/1/Types">0174587</offer>
<type2 xmlns="http://schema.peters.com/doc_353/1/Types">014717</type2>
<supplier xmlns="http://schema.peters.com/doc_353/1/Types">019172</supplier>
<id_frame xmlns="http://schema.peters.com/doc_353/1/Types" />
<type3 xmlns="http://schema.peters.com/doc_353/1/Types">
<type2 />
<main>false</main>
</type3>
<status xmlns="http://schema.peters.com/doc_353/1/Types">Some state</status>
</insert>
</ArrayOfInserts>
Después de llamar a RemoveAllNamespaces (xmlWithLotOfNs), deberíamos obtener:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfInserts>
<insert>
<offer >0174587</offer>
<type2 >014717</type2>
<supplier >019172</supplier>
<id_frame />
<type3 >
<type2 />
<main>false</main>
</type3>
<status >Some state</status>
</insert>
</ArrayOfInserts>
El idioma preferido de la solución es C # en .NET 3.5 SP1.
Respuestas:
Bueno, aquí está la respuesta final. He utilizado la gran idea de Jimmy (que desafortunadamente no está completa) y la función de recursividad completa para que funcione correctamente.
Basado en la interfaz:
Represento aquí la solución C # limpia y universal final para eliminar espacios de nombres XML:
Está funcionando al 100%, pero no lo he probado mucho por lo que puede que no cubra algunos casos especiales ... Pero es una buena base para empezar.
fuente
La respuesta etiquetada más útil tiene dos defectos:
Aquí está mi opinión sobre esto:
Código de muestra aquí .
fuente
xmlns
también.(from a in e.Attributes().DistinctBy(x => x.Name.LocalName)
para el casolang=""ru-ru"" xml:lang=""ru-ru""
la respuesta obligatoria usando LINQ:
fuente
Eso hará el truco :-)
fuente
Recójalo de nuevo, en C # - línea agregada para copiar los atributos:
fuente
La respuesta obligatoria usando XSLT:
fuente
Y esta es la solución perfecta que también eliminará elementos XSI. (Si elimina los xmlns y no elimina XSI, .Net le grita ...)
fuente
Regex.Replace(xmlStr, @"<(/?)([^>\s:]+):([^>]+)>", "<$1$3>")
Sé que esta pregunta supuestamente está resuelta, pero no estaba totalmente satisfecho con la forma en que se implementó. Encontré otra fuente aquí en los blogs de MSDN que tiene una
XmlTextWriter
clase anulada que elimina los espacios de nombres. Lo modifiqué un poco para obtener algunas otras cosas que quería, como un formato bonito y la conservación del elemento raíz. Esto es lo que tengo en mi proyecto en este momento.http://blogs.msdn.com/b/kaevans/archive/2004/08/02/206432.aspx
Clase
Uso
fuente
Esta es una solución basada en la respuesta aceptada de Peter Stegnar.
Lo usé, pero (como comentaron andygjp y John Saunders) su código ignora los atributos .
También necesitaba cuidar los atributos, así que adapté su código. La versión de Andy era Visual Basic, esto sigue siendo C #.
Sé que ha pasado un tiempo, pero quizás algún día le ahorre a alguien algo de tiempo.
fuente
Me gustó mucho el lugar al que va Dexter, así que lo traduje a un método de extensión "fluido":
El enfoque "fluido" me permite hacer esto:
fuente
Puedes hacerlo usando Linq:
fuente
La respuesta de Peter ligeramente modificada, esto también funcionaría bien para el atributo, incluida la eliminación del espacio de nombres y el prefijo. Un poco de pena porque el código se ve un poco feo.
fuente
Las respuestas de Jimmy y Peter fueron de gran ayuda, pero en realidad eliminaron todos los atributos, así que hice una pequeña modificación:
fuente
Este es un poco tarde para la fiesta, pero esto es lo que usé recientemente:
(tomado de este hilo de MSDN )
Editar Según el comentario a continuación, parece que si bien esto elimina el prefijo del espacio de nombres de los nodos, en realidad no elimina el atributo xmlns. Para hacer eso, también debe restablecer el nombre de cada nodo a su nombre local (por ejemplo, nombre menos espacio de nombres)
fuente
Para que los atributos funcionen, el bucle for para agregar atributos debe ir después de la recursividad, también es necesario verificar si IsNamespaceDeclaration:
fuente
Aquí está mi versión VB.NET de Dexter Legaspi C # Version
fuente
Otra solución que tiene en cuenta la posibilidad de entrelazar nodos TEXT y ELEMENT, por ejemplo:
Código:
fuente
Sin recurrir a una solución basada en XSLT, si lo que desea es limpio, elegante e inteligente, necesitaría algo de apoyo del marco, en particular, el patrón de visitantes podría hacer que esto sea muy sencillo. Desafortunadamente, no está disponible aquí.
Lo he implementado inspirado en LINQ
ExpressionVisitor
para tener una estructura similar. Con esto, puede aplicar el patrón de visitante a objetos XML (LINQ-to-). (He hecho pruebas limitadas en esto, pero funciona bien por lo que puedo decir)ps, esta implementación en particular usa algunas características de .NET 4 para hacer la implementación un poco más fácil / limpia (uso de
dynamic
argumentos predeterminados). No debería ser demasiado difícil hacerlo compatible con .NET 3.5, quizás incluso compatible con .NET 2.0.Luego, para implementar el visitante, aquí hay uno generalizado que puede cambiar múltiples espacios de nombres (y el prefijo utilizado).
Y un pequeño método de ayuda para hacer rodar la pelota:
Luego, para eliminar un espacio de nombres, puede llamarlo así:
Con este visitante, puede escribir un
INamespaceMappingManager
para eliminar todos los espacios de nombres.fuente
Solución simple que realmente cambia el nombre de los elementos en el lugar, sin crear una copia, y hace un buen trabajo reemplazando los atributos.
Nota: esto no siempre conserva el orden de los atributos originales, pero estoy seguro de que podría cambiarlo para hacerlo con bastante facilidad si es importante para usted.
También tenga en cuenta que esto también podría generar una excepción, si tuviera atributos de XElement que solo sean únicos con el espacio de nombres, como:
que realmente parece un problema inherente. Pero dado que la pregunta indicaba generar un String, no un XElement, en este caso podría tener una solución que generaría un String válido que fuera un XElement no válido.
También me gustó la respuesta de jocull usando un XmlWriter personalizado, pero cuando lo probé, no funcionó para mí. Aunque todo parece correcto, no puedo decir si la clase XmlNoNamespaceWriter tuvo algún efecto; definitivamente no estaba eliminando los espacios de nombres como yo quería.
fuente
Agregar my que también limpia el nombre de los nodos que tienen prefijos de espacio de nombres:
fuente
Probé las primeras soluciones y no funcionó para mí. Principalmente el problema con la eliminación de atributos como los demás ya se han mencionado. Yo diría que mi enfoque es muy similar al de Jimmy al usar los constructores XElement que toman el objeto como parámetros.
fuente
mi respuesta,
código más ligero , basado en la manipulación de cadenas ,
fuente
Aquí están Regex Reemplazar una línea:
Aquí hay una muestra: https://regex101.com/r/fopydN/6
Advertencia: ¡puede haber casos extremos!
fuente
La respuesta de user892217 es casi correcta. No se compilará como está, por lo que necesita una pequeña corrección en la llamada recursiva:
fuente
Esto funcionó para mí.
fuente
Después de mucho buscar una solución a este mismo problema, esta página en particular parecía tener la mayor parte de la carne ... sin embargo, nada encajaba exactamente, así que tomé la forma antigua y simplemente analicé las cosas que quería eliminar. Espero que esto ayude a alguien. (Nota: esto también elimina el SOAP o sobres similares).
fuente
Sin recrear la jerarquía de nodos completa:
fuente
Probé algunas de las soluciones, pero como muchos afirman, hay algunos casos extremos.
Usé algunas de las expresiones regulares anteriores, pero llegué a la conclusión de que una expresión regular de un paso no es factible.
Así que aquí está mi solución, expresión regular de 2 pasos, buscar etiquetas, eliminar dentro de las etiquetas, no alterar cdata:
Por ahora está funcionando al 100% para mí.
fuente
Aquí hay una solución basada en expresiones regulares para este problema ...
fuente
Creo que esta es la respuesta más corta (pero para construcciones como, tendrás otra discusión, también tengo regex para convertir
"<bcm:info></bcm:info>"
a "<info></info>
" pero no estaba optimizado, si alguien me pregunta, lo compartiré. Entonces, mi solución es:fuente