2010-05-21 12 views
5

Mi módulo java obtiene un enorme xml de entrada de un mainframe. Por desgracia, la unidad central no puede omitir elementos opcionales, con el resultado de que tengo una gran cantidad de etiquetas vacías en mi entrada:cómo eliminar las etiquetas vacías en la entrada xml

Así,

<SSN>111111111</SSN> 
<Employment> 
<Current> 
<Address> 
<line1/> 
<line2/> 
<line3/> 
<city/> 
<state/> 
<country/> 
</Address> 
<Phone> 
<phonenumber/> 
<countryCode/> 
</Phone> 
</Current> 
<Previous> 
<Address> 
<line1/> 
<line2/> 
<line3/> 
<city/> 
<state/> 
<country/>  
</Address> 
<Phone> 
<phonenumber/> 
<countryCode/> 
</Phone> 
</Previous> 
</Employment> 
<MaritalStatus>Single</MaritalStatus> 

debería ser:

<SSN>111111111</SSN> 
<MaritalStatus>SINGLE</MaritalStatus> 

I use jaxb para deshacer la cadena de entrada xml que el mainframe le envía. ¿Existe alguna manera limpia/fácil de eliminar todas las etiquetas de grupo vacías, o tengo que hacer este manual en el código para cada elemento? Tengo más de 350 elementos en mi entrada xml, así que me encantaría si jaxb tuviera una forma de hacerlo automáticamente?

Gracias, SGB

Respuesta

4

Se podía procesar previamente mediante XSLT. Sé que se considera un poco "Disco" hoy en día, pero es rápido y fácil de aplicar.

De esta discusión tek-tips, puede transformar con XSLT para eliminar elementos vacíos.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
    <xsl:if test=". != '' or ./@* != ''"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 
+0

interesante. Gracias por su sugerencia. Esperaba que hubiera una forma de hacer que Jaxb lo hiciera automágicamente :) ¿Alguien sabe si es posible lograr lo mismo en jaxb? Si no, parece que tendré que probar esto. Gracias de nuevo. – SGB

4

Creo que tendrías que editar tu código de mainframe para la mejor solución. Cuando su mainframe genera el XML, tendrá que decirle que no muestre una etiqueta si está vacía.

No hay mucho que pueda hacer en el lado del cliente, no creo. Si el XML que recibe está lleno de etiquetas vacías, entonces no tiene más remedio que analizarlas todas; después de todo, ¿cómo puede saber si una etiqueta está vacía sin analizarla de alguna manera?

Pero tal vez usted podría hacer una cadena de expresiones regulares reemplazar en el texto XML antes de JAX-B llega a que:

String xml = //get the XML 
xml = xml.replaceAll("<.*?/>", ""); 

Esto eliminará las etiquetas vacías como "< ciudad/>", pero no "< Dirección > </Dirección > ".

+0

Se suponía que la gente de Mainframe solo me enviaba elementos no vacíos. Sin embargo, su analizador interno está teniendo problemas. Están omitiendo correctamente los nodos de hoja que están vacíos. Sin embargo, cuando se trata de un grupo/elementos complejos con nodos secundarios, no pueden hacerlo. De ahí mi intento de arreglarlo de mi lado. – SGB

+0

¡Debería estar encantado de haber convencido a sus programadores de COBOL para que escriban XML en primer lugar! Logré hacer esto aproximadamente en 2004 (¡parece años atrás!) Y mi amigo de programación de COBOL, Eamonn (quien tristemente perdió una pequeña fortuna en acciones de empleados cuando se cayó Worldcom) dijo "¿Sabes qué ?, esta cosa XML podría ser solo ¡útil!". Eamonn también desarrolló su propio analizador local, había un analizador de terceros disponible, ¡pero simplemente no estaba interesado en correr con el código de otra persona! – blissapp

1

La única técnica que conozco en JAXB para hacer esto es escribiendo un XmlAdapter personalizado que colapsa las cadenas vacías en nulos.

El inconveniente es que tendría que agregar esto como una anotación a cada elemento de su código, y si tiene 350 de ellos, eso va a ser tedioso.

+0

Hola Skaffman, ¿Podría indicarme un ejemplo ... quizás un enlace? gracias SGB – SGB

1

Ok, de vez en cuando intervino aquí. Solución de trabajo simple con jaxb (al menos para jdk 1.6.x):

¡establezca el atributo o elemento no deseado nulo! p. ... setEmployment (null); , entonces toda la estructura de Empleo ha desaparecido.

Saludos Masi

0
public static void main(String[] args) { 

    final String regex1 = "<([a-zA-Z][a-zA-Z0-9]*)[^>]*/>"; 
    final String regex2 = "<([a-zA-Z][a-zA-Z0-9]*)[^>]*>\\s*</\\1>"; 

    String xmlString = "<SSN>111111111</SSN><Employment><Current><Address><line1/><line2/><line3/><city/><state/><country/></Address><Phone><phonenumber/><countryCode/></Phone></Current><Previous><Address><line1/><line2/><line3/><city/><state/><country/> </Address><Phone><phonenumber/><countryCode/></Phone></Previous></Employment><MaritalStatus>Single</MaritalStatus>"; 
    System.out.println(xmlString); 

    final Pattern pattern1 = Pattern.compile(regex1); 
    final Pattern pattern2 = Pattern.compile(regex2); 

    Matcher matcher1; 
    Matcher matcher2; 
    do { 
     matcher1 = pattern1.matcher(xmlString); 
     matcher2 = pattern2.matcher(xmlString); 
     xmlString = xmlString.replaceAll(regex1, "").replaceAll(regex2, ""); 
    } while (matcher1.find() || matcher2.find()); 

    System.out.println(xmlString); 
} 

Consola:

<SSN>111111111</SSN> 
<Employment> 
    <Current> 
     <Address> 
      <line1/> 
      <line2/> 
      <line3/> 
      <city/> 
      <state/> 
      <country/> 
     </Address> 
     <Phone> 
      <phonenumber/> 
      <countryCode/> 
     </Phone> 
    </Current> 
    <Previous> 
     <Address> 
      <line1/> 
      <line2/> 
      <line3/> 
      <city/> 
      <state/> 
      <country/> 
     </Address> 
     <Phone> 
      <phonenumber/> 
      <countryCode/> 
     </Phone> 
    </Previous> 
</Employment> 
<MaritalStatus>Single</MaritalStatus> 

<SSN>111111111</SSN> 
<MaritalStatus>Single</MaritalStatus> 

Online demo here

Cuestiones relacionadas