2012-02-17 12 views
13

Todo lo que hace con XML distingue entre mayúsculas y minúsculas, lo sé.Analizador XML insensible a mayúsculas/minúsculas en C#

Sin embargo, en este momento me encuentro en una situación, donde el software que estoy escribiendo produciría mucho menos errores si de alguna manera hice nombre XML/atribuir caso el reconocimiento insensibles. El XPath insensible a las mayúsculas y minúsculas sería un dios enviado.

¿Hay una manera fácil/biblioteca para hacer que en C#?

+0

No es probable. Pero que podría ser 'XElement.Parse (xmlText.Tolower())' –

+0

un documento XML puede tener dos elementos diferentes * * nombrados respectivamente: '' MyName' y myName' - que están destinados a ser diferente. Convertirlos/tratarlos con el mismo nombre es un error que puede tener graves consecuencias. –

Respuesta

14

un documento XML puede tener dos elementos diferentes nombrados respectivamente: MyName y myName - que están destinados a ser diferente. Convertirlos/tratarlos con el mismo nombre es un error que puede tener graves consecuencias.

En caso de que el anterior no es el caso, entonces aquí es una solución más precisa, utilizando XSLT para procesar el documento en uno que sólo tiene los nombres de elementos minúsculas y nombres de atributo minúsculas:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="vUpper" select= 
"'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> 

<xsl:variable name="vLower" select= 
"'abcdefghijklmnopqrstuvwxyz'"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[name()=local-name()]" priority="2"> 
    <xsl:element name="{translate(name(), $vUpper, $vLower)}" 
    namespace="{namespace-uri()}"> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="*" priority="1"> 
    <xsl:element name= 
    "{substring-before(name(), ':')}:{translate(local-name(), $vUpper, $vLower)}" 
    namespace="{namespace-uri()}"> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="@*[name()=local-name()]" priority="2"> 
    <xsl:attribute name="{translate(name(), $vUpper, $vLower)}" 
    namespace="{namespace-uri()}"> 
     <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 

<xsl:template match="@*" priority="1"> 
    <xsl:attribute name= 
    "{substring-before(name(), ':')}:{translate(local-name(), $vUpper, $vLower)}" 
    namespace="{namespace-uri()}"> 
    <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 
</xsl:stylesheet> 

cuando esta transformación se aplica en cualquier documento XML, por ejemplo, éste:

<authors xmlns:user="myNamespace"> 
    <?ttt This is a PI ?> 
    <Author xmlns:user2="myNamespace2"> 
    <Name idd="VH">Victor Hugo</Name> 
    <user2:Name idd="VH">Victor Hugo</user2:Name> 
    <Nationality xmlns:user3="myNamespace3">French</Nationality> 
    </Author> 
    <!-- This is a very long comment the purpose is 
     to test the default stylesheet for long comments--> 
    <Author Period="classical"> 
    <Name>Sophocles</Name> 
    <Nationality>Greek</Nationality> 
    </Author> 
    <author> 
    <Name>Leo Tolstoy</Name> 
    <Nationality>Russian</Nationality> 
    </author> 
    <Author> 
    <Name>Alexander Pushkin</Name> 
    <Nationality>Russian</Nationality> 
    </Author> 
    <Author Period="classical"> 
    <Name>Plato</Name> 
    <Nationality>Greek</Nationality> 
    </Author> 
</authors> 

el resultado deseado, correcta (nombres de elementos y atributos c onverted en minúsculas) se produce:

<authors><?ttt This is a PI ?> 
    <author> 
     <name idd="VH">Victor Hugo</name> 
     <user2:name xmlns:user2="myNamespace2" idd="VH">Victor Hugo</user2:name> 
     <nationality>French</nationality> 
    </author><!-- This is a very long comment the purpose is 
     to test the default stylesheet for long comments--> 
    <author period="classical"> 
     <name>Sophocles</name> 
     <nationality>Greek</nationality> 
    </author> 
    <author> 
     <name>Leo Tolstoy</name> 
     <nationality>Russian</nationality> 
    </author> 
    <author> 
     <name>Alexander Pushkin</name> 
     <nationality>Russian</nationality> 
    </author> 
    <author period="classical"> 
     <name>Plato</name> 
     <nationality>Greek</nationality> 
    </author> 
</authors> 

Una vez que el documento se convierte a su forma deseada, a continuación, puede realizar cualquier procesamiento deseado en el documento convertido.

+0

se ve muy bien! –

+0

@ArsenZahray: De nada. –

7

XML es texto. Solo ToLower antes de cargarlo en el analizador que esté usando.

Siempre y cuando usted no tiene que validar contra un esquema y no le importa los valores que se están en minúsculas, esto debería funcionar bien.


El hecho es que cualquier analizador XML se entre mayúsculas y minúsculas. Si no fuera así, no sería un analizador XML.

+8

Pero probablemente no desee 'ToLower' sus valores – CaffGeek

+1

@Chad - Probablemente. Puse esa advertencia en mi respuesta. – Oded

+0

He pensado en eso. En la mayoría de los casos, esto funcionaría, excepto que a veces los campos pueden contener información, en la que deseo que se conserve el caso. Como, por ejemplo, contraseñas, hashes y otras cosas para el mundo externo. Por otro lado, realmente no necesito diferenciar entre nombre y atributos de nombre en xhtml –

11

Puede crear métodos de mayúsculas y minúsculas (extensiones de usabilidad), ej .:

public static class XDocumentExtensions 
{ 
    public static IEnumerable<XElement> ElementsCaseInsensitive(this XContainer source, 
     XName name) 
    { 
     return source.Elements() 
      .Where(e => e.Name.Namespace == name.Namespace 
       && e.Name.LocalName.Equals(name.LocalName, StringComparison.OrdinalIgnoreCase)); 
    } 
} 
0

Comenzaría por convertir todas las etiquetas y los nombres de los atributos a minúsculas, dejando los valores intactos, mediante el uso del análisis SAX, es decir. con XmlTextReader.