2010-05-21 11 views
5

Mein Java-Modul erhält eine große Eingabe XML von einem Mainframe. Leider ist der Mainframe nicht in der Lage ist, optionale Elemente zu überspringen, mit dem Ergebnis, dass ich eine Menge von leeren Tags in meinem Input bekommen:So entfernen Sie leere Tags in Eingabe-XML

So

<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> 

sollte sein:

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

I Verwenden Sie jaxb, um die Eingabe-XML-Zeichenfolge, die der Mainframe sendet, aufzulösen. Gibt es eine saubere/einfache Möglichkeit, alle leeren Gruppen-Tags zu entfernen, oder muss ich das manuell im Code für jedes Element tun. Ich habe über 350 Elemente in meinem Eingabe-XML, also würde ich es lieben, wenn Jaxb selbst eine Möglichkeit hätte, dies automatisch zu tun?

Danke, SGB

Antwort

4

Sie Vorprozess XSLT verwenden könnte. Ich weiß, dass es heutzutage ein bisschen "Disco" ist, aber es ist schnell und einfach anzuwenden.

Von dieser tek-tips Diskussion könnten Sie mit XSLT transformieren, um leere Elemente zu entfernen.

<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

interessant. Danke für Ihren Vorschlag. Ich hatte gehofft, dass es einen Weg geben würde, jaxb es automatisch zu machen :) Weiß jemand, ob es möglich ist, dasselbe in jaxb zu erreichen? Wenn nicht, sieht es so aus, als ob ich das versuchen muss. Danke nochmal. – SGB

4

Ich denke, Sie müssten Ihren Mainframe-Code für die beste Lösung bearbeiten. Wenn Ihr Mainframe den XML-Code generiert, müssen Sie ihm mitteilen, dass er kein Tag ausgeben soll, wenn er leer ist.

Es gibt nicht viel, was Sie auf der Clientseite tun können, glaube ich nicht. Wenn das XML, das Sie erhalten, mit leeren Tags gefüllt ist, haben Sie keine andere Wahl als sie alle zu parsen. Wie können Sie feststellen, ob ein Tag leer ist, ohne es in irgendeiner Weise zu analysieren?

Aber vielleicht könnten Sie eine Regex Zeichenfolge auf dem XML-Text vor JAX-B wird um es ersetzen tun:

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

Dies entfernt leere Tags wie "< Stadt/>", aber nicht "<Adresse> </Adresse > ".

+0

Die Mainframe-Leute sollten mir nur nicht-leere Elemente schicken, aber ihr hauseigener Parser hat Probleme. Sie schließen Blattknoten, die leer sind, korrekt aus. Wenn es sich jedoch um eine Gruppe/komplexe Elemente mit untergeordneten Knoten handelt, können sie dies nicht tun. Daher mein Versuch, es auf meiner Seite zu reparieren. – SGB

+0

Sie sollten erfreut sein, dass Sie Ihre COBOL-Programmierer davon überzeugt haben, überhaupt XML zu schreiben! Ich schaffte es ungefähr 2004 (scheint vor Jahren!) Und mein COBOL-Programmierungsfreund Eamonn (der leider ein kleines Vermögen in realisierten Mitarbeiteroptionsaktien verlor, als Worldcom zusammenbrach) sagte tatsächlich: "Weißt du was, diese XML-Sache könnte einfach sein sinnvoll!". Eamonn entwickelte auch seinen eigenen selbst entwickelten Parser, es gab einen Parser für Dritte, aber er war einfach nicht daran interessiert, mit dem Code eines anderen zu laufen! – blissapp

1

Die einzige Technik, die ich in JAXB kenne, um dies zu tun ist, indem Sie eine benutzerdefinierte XmlAdapter schreiben, die Ihre leeren Strings zu Nullen zusammenfasst.

Der Nachteil ist, dass Sie dies als eine Anmerkung zu jedem einzelnen Element in Ihrem Code hinzufügen müssen, und wenn Sie 350 von ihnen haben, wird das langweilig.

+0

Hallo Skaffman, Könnten Sie mich bitte auf ein Beispiel hinweisen ... vielleicht einen Link? danke SGB – SGB

1

Ok, accionional trat hier ein. Einfache Arbeitslösung mit Jaxb (mindestens für jdk 1.6.x):

setzen Sie das unerwünschte Attribut oder Element null! z.B. ... setEmployment (null); dann ist die gesamte Beschäftigungsstruktur weg.

Prost 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); 
} 

Console:

<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

Verwandte Themen