XML Document Parsen und Ausgeben mit Suchfunktion

Stiffler

Mitglied
Hallo ins Forum,

ich muss vorweg gestehen ich habe mich die Komplette letzte Woche erst mit Java beschäftigt. (bitte nehmt es mir also nicht Krum wie die Frage vielleicht Blöd ist.)

Da ich gesucht habe bei Google und auch hier im Forum und nicht so richtig fündig geworden bin kommt hier mal meine Frage.

Ich habe ein Projekt wo ich aus einem kleinen Tool (zugänglich leider nur für 2 Personen) mir die Informationen in ein *.xml Dokument exportieren kann.
Dieses Dokument da es glaube über 15k Zeilen hat wollte ich Parsen und das dann vielleicht über eine GUI oder über WEB Seiten Zugriff mit einem Suchfeld Durchsuchen und dann nur den einzelnen Wert + Child Elemente ausgeben.

Ich scheitere aber nun einfach schon beim Einlesen.
Java:
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.util.ArrayList;

public class AdminTool3Shape {
    //Pfad und Name der XML Datei die Geparst werden soll
    private static String XMLDateiName = "\\\\xxx.xxx.xxx.xxx\\xxxxx\\xxxxxxx\\xxxxxx\\07 - Projekte\\06 - Java\\3ShapeExport.xml";
    private static String Site, Description, Dongle, Application, Attribute ;
    private static ArrayList<String> liste;
    private static ArrayList<SiteList> liste2;

    public static void main(String[] args) throws Exception, Exception {
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         DocumentBuilder builder = factory.newDocumentBuilder();
         // Uebergebene XML-Datei parsen
         Document dokument = builder.parse(new File(XMLDateiName));
         dokument.getDocumentElement();
         getAlleSite(dokument);
         getAlleDescription(Dongle, Application, Attribute, dokument);
        
         // DOM Baum durchlaufen und ausgeben
         traversieren(dokument.getDocumentElement(), "");
        
    }
    private static void traversieren(Element d, String dongle) {       
        System.out.println(dongle + d.getNodeName());
        // Kindelemente des uebergebenen Elements ermitteln
        NodeList children = d.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node knoten = children.item(i);
            // Knoten ist ein ELEMENT_NODE
            if (knoten.getNodeType() == Node.ELEMENT_NODE)
                // Rekursiver Aufruf von traversieren für aktuelles Element
                traversieren((Element) knoten, dongle + " ");
            // Knoten ist ein TEXT_NODE
            else if (knoten.getNodeType() == Node.TEXT_NODE) {
                    String inhalt = knoten.getTextContent();
                    if (inhalt.trim().length() > 0) // leerer Inhalt?
                    System.out.println(dongle + " :" + inhalt);
        } else
        // kein ELEMENT_NODE, kein TEXT_NODE
        System.out.println(dongle + knoten);
        }
    }
    private static ArrayList<String> getAlleSite(Document dokument) {
        // Alle Kindelemente mit dem Site Description einsammeln
        NodeList siteNodes = dokument.getElementsByTagName("Site");
        liste = new ArrayList<String>(siteNodes.getLength());
            for (int i=0; i<siteNodes.getLength(); i++) {
        // Node nach Element casten
                Element siteElement = (Element) siteNodes.item(i);
        // Neue Instanz von Site anlegen
                Site abschnitt = new Site(null, Site, Description, Dongle, Application, Attribute, XMLDateiName);
        // Kindelemente Description suchen, den Textinhalt als Description nehmen
                NodeList node1 = siteElement.getElementsByTagName("Description");
                Site.setDescription(node1.item(0).getTextContent());
        // Analog für Dongle
                NodeList node2 = siteElement.getElementsByTagName("Dongle");
                Site.setDongle(node2.item(0).getTextContent());
        
                Description=Site.getDescription();
                Dongle=Site.getDongle();
                liste.add(Description+" "+Dongle);
    
        }
        
        // Kontroll Ausgabe der Liste auf der Konsole
        System.out.println("*** All Site ***");
        System.out.println(liste);
        return liste;
    }
    public static ArrayList<SiteList> getAdressenDaten(String Site, String Description, Document dokument){
        NodeList site= dokument.getElementsByTagName("Site");     
        NodeList description= dokument.getElementsByTagName("Description");
        NodeList Dongle= dokument.getElementsByTagName("Dongle");
        NodeList Application=dokument.getElementsByTagName("Application");
        NodeList Attribute=dokument.getElementsByTagName("Attribute");
        
        liste2 = new ArrayList<SiteList>(liste.size());
        for (int i =0;i<liste.size();i++){
        String pSite=site.item(i).getTextContent();
        String pDescription=description.item(i).getTextContent();             
        String pDongle=Dongle.item(i).getTextContent();
        String pApplication=Application.item(i).getTextContent();
        String pAttribute=Attribute.item(i).getTextContent();
        
        
        SiteList s= new SiteList();
        s.setSite(pSite);
        s.setDescription(pDescription);
        s.setDongle(pDongle);
        s.setApplication(pApplication);
        s.setAttribute(pAttribute);       
        liste2.add(site);
        }
       }
        System.out.println(liste2);
        return liste2;
                
    }
    public static void getAlleDescription (Document dokument) {
        NodeList Site= dokument.getElementsByTagName("Site");     
        NodeList Description= dokument.getElementsByTagName("Description");
        liste = new ArrayList<String> (Site.getLength());
        
        for (int i=0; i<Site.getLength();i++){
            Site.item(i).getTextContent();
            Description.item(i).getTextContent();
        liste.add(Site+" " +Description); 
        }
        
    }   
    private static void getAlleDescription(String dongle2, String application2, String attribute2, Document dokument) {       
        
    }
    public static String getXMLDateiName() {
        return XMLDateiName;
    }
    public static void setXMLDateiName(String xMLDateiName) {
        XMLDateiName = xMLDateiName;
    }
    public static String getSite() {
        return Site;
    }
    public static void setSite(String site) {
        Site = site;
    }
    public static String getDescription() {
        return Description;
    }
    public static void setDescription(String description) {
        Description = description;
    }
    public static String getDongle() {
        return Dongle;
    }
    public static void setDongle(String dongle) {
        Dongle = dongle;
    }
    public static String getApplication() {
        return Application;
    }
    public static void setApplication(String application) {
        Application = application;
    }
    public static String getAttribute() {
        return Attribute;
    }
    public static void setAttribute(String attribute) {
        Attribute = attribute;
    }    
}


Ich zeig euch Exemplarisch auch mal die Exportierte *.xml


XML:
<?xml version="1.0"?>
<SiteExport Version="1.0">
  <CustomerName>Firma</CustomerName>
  <SiteList>
    <Site ID="09051">
      <Description>000_XXX_1271101190</Description>
      <ResellersCustomerNo></ResellersCustomerNo>
      <ResellersCustomID1 Label="Custom ID 1"></ResellersCustomID1>
      <ResellersCustomID2 Label="Custom ID 2"></ResellersCustomID2>
      <ResellersCustomID3 Label="Custom ID 3"></ResellersCustomID3>
      <Notes></Notes>
      <CanReceive>True</CanReceive>
      <Dongles>
        <Dongle Number="1271101190">
          <Application Name="DentalDesigner Premium">
            <Attribute>Expired</Attribute>
            <Attribute>Saves limited</Attribute>
            <Attribute>Client points: 1</Attribute>
            <Attribute>Installed version: 2.8.8.4</Attribute>
          </Application>
          <Application Name="DentalManager">
            <Attribute>Encryption enabled</Attribute>
            <Attribute>Expired</Attribute>
            <Attribute>Client points: 3</Attribute>
            <Attribute>Options: Abutments OBSOLETE from 2010</Attribute>
            <Attribute>Installed version: 2.8.8.4</Attribute>
          </Application>
          <Application Name="DentalManager Inbox module">
            <Attribute>Expired</Attribute>
            <Attribute>Client points: 3</Attribute>
          </Application>
          <Application Name="ScanIt Impression">
            <Attribute>Saves limited</Attribute>
          </Application>
          <Application Name="Abutment Designer Module Save Limited DEMO">
            <Attribute>Saves limited</Attribute>
          </Application>
          <Application Name="Removable Design Module">
            <Attribute>Saves limited</Attribute>
            <Attribute>Client points: 1</Attribute>
          </Application>
          <Application Name="Implant Bars/Bridge Design Module">
            <Attribute>Saves limited</Attribute>
            <Attribute>Client points: 1</Attribute>
          </Application>
          <Application Name="Model Builder (TRIOS scans only)">
            <Attribute>Saves limited</Attribute>
            <Attribute>Client points: 1</Attribute>
          </Application>
          <Application Name="Model Builder (3rd Party scans)">
            <Attribute>Saves limited</Attribute>
            <Attribute>Client points: 1</Attribute>
          </Application>
          <Application Name="Model Builder (Impression scans)">
            <Attribute>Saves limited</Attribute>
            <Attribute>Client points: 1</Attribute>
          </Application>
        </Dongle>
      </Dongles>
      <Connections>
        <Connection ReceiverSiteID="14065">
          <Notes></Notes>
          <CreateDate>2012-06-25</CreateDate>
        </Connection>
      </Connections>
      <Options>
        <Option Name="RawSTL" Description="Raw STL CAD Output for all customers"/>
        <Option Name="RK" Description="Rübeling und Klar CAD Output for all customers"/>
        <Option Name="3DPrinter" Description="3D Printer CAD Output for all customers"/>
        <Option Name="RestorationMill" Description="RestorationMill CAD Output for all customers"/>
        <Option Name="BEGO" Description="BEGO CAD Output"/>
        <Option Name="DentMill" Description="DentMill CAD Output for all customers"/>
        <Option Name="RawSTLExceptLocked" Description="Raw STL (except locked) OBSOLETE! for all customers"/>
        <Option Name="GeneralRPMachine" Description="RP machine with supports CAD Output for all customers"/>
        <Option Name="Mandatory 1" Description="Mandatory 1"/>
        <Option Name="WielandZeno40" Description="Zeno CAM 4.0 CAD Output"/>
        <Option Name="3IImplantSignature1" Description="3I Implant Signature 1 for all customers"/>
        <Option Name="FollowMe" Description="Follow Me CAD Output for all customers"/>
        <Option Name="BEGO-Semados" Description="BEGO abutment kit"/>
        <Option Name="SII_STLOutput" Description="ScanIt Impression STL output"/>
        <Option Name="RawDCM" Description="Raw DCM CAD Output for all customers"/>
        <Option Name="SIR_STLOutput" Description="ScanIt Restoration STL output"/>
        <Option Name="Wieland-Abutments" Description="Wieland abutment kit for all customers"/>
        <Option Name="VisualizationOutput" Description="Visualization output for all customers"/>
        <Option Name="Camlog" Description="Camlog Implant Kit for all customers"/>
        <Option Name="Neoss" Description="Neoss Implant Kit for all customers"/>
        <Option Name="Avinent Protech Implant Library" Description="Avinent Protech Implant Library (Option D) for all customers"/>
        <Option Name="BioHorizons" Description="Implantlibrary of BioHorizons for all customers"/>
        <Option Name="ZimmerAbutmentKit" Description="Zimmer Abutment Kit (Option B) for all customers"/>
        <Option Name="ZimmerImplantSignature1" Description="Zimmer Implant Signature 1 (Option B) for all customers"/>
        <Option Name="Core3d Implant library" Description="Core3d Implant library (Option D) for all customers"/>
        <Option Name="Jorge Test" Description="Jorge Test for all customers"/>
        <Option Name="BEGOCrownLibrary" Description="BEGO Crown Library"/>
        <Option Name="RawSTL" Description="Raw STL CAD Output"/>
        <Option Name="GlidewellHybridKit" Description="GlidewellHybridKit for all customers"/>
        <Option Name="GlidewellBarKit" Description="GlidewellBarKit for all customers"/>
        <Option Name="BegoAbutmentKit" Description="BegoAbutmentKit for all customers"/>
        <Option Name="GlidewellAnatomyLibrary" Description="GlidewellAnatomyLibrary for all customers"/>
        <Option Name="Unlimited Implant Scanning" Description="Unlimited Implant Scanning"/>
        <Option Name="TriosInbox" Description="Trios Inbox enabling option for all customers"/>
        <Option Name="VertexDental Quint Denture SmileLibrary" Description="VertexDental Quint Denture SmileLibrary (Option C) for all customers"/>
        <Option Name="Pala Smile library" Description="Pala® Smile library (Option D) for all customers"/>
      </Options>
    </Site>
</SiteList>

Ich hoffe ich hab nur ein Vertipper drin oder ich bin doch total Blöd :D

Freu mich auf ein bissel Hilfe :)
Sollte ich euch im Bezug auf Mediendesign oder gar bei der Fotografie helfen können immer her mit euren Fragen.
 

mihe7

Top Contributor
Interessant wäre, wonach Du die Datei durchsuchen willst und was in welchem Fall wie ausgegeben werden soll.
 

Stiffler

Mitglied
Ich möchte am Ende des Projektes nach der Dongle Nummer suchen und mir dann Ausgeben lassen was unter Dongle steht <Application> & <Attribute>
 

mihe7

Top Contributor
Wenn Du nur einmal etwas aus der Datei lesen willst, könntest Du es mit XPath versuchen. Ansonsten würde ich einen SAXParser bevorzugen, sieht dann in etwa so aus:
Java:
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

import java.util.*;
import java.io.*;

public class Test {
    static class Application {
        private final String name;
        private final List<String> attributes;
    
        public Application(String name, List<String> attributes) {
            this.name = name;
            this.attributes = attributes;
        }
    }

    static class Dongle {
        private final String name;
        private final List<Application> applications;

        public Dongle(String name, List<Application> applications) {
            this.name = name;
            this.applications = applications;
        }
    }

    static class DongleHandler extends DefaultHandler {
        boolean getText = false;
        StringBuilder text;
        String dongleName;
        String applicationName;
        List<String> applicationAttributes = new ArrayList<>();
        List<Application> applications = new ArrayList<>();
        List<Dongle> dongles = new ArrayList<>();

        public List<Dongle> getDongles() { return dongles; }

        public void startElement(String uri, String localName, String qName, 
                Attributes atts) throws SAXException {    
            switch(qName) {
                case "Dongle": 
                    dongleName = atts.getValue("Number"); 
                    applications = new ArrayList<>();
                    break;
                case "Application": 
                    applicationName = atts.getValue("Name");
                    applicationAttributes = new ArrayList<>();
                    break;
                case "Attribute":
                    text = new StringBuilder();
                    getText = true;
                    break;
                default: break;
            }
        }

        public void characters(char[] ch, int start, int length) {
            if (getText) {
                text.append(ch, start, length);
            }
        }

        public void endElement(String uri, String localName, String qName) {
            switch(qName) {
                case "Attribute": 
                    applicationAttributes.add(text.toString());
                    getText = false;
                    break;
                case "Application":
                    applications.add(new Application(applicationName, applicationAttributes));
                    break;
                case "Dongle":
                    dongles.add(new Dongle(dongleName, applications));
                    break;
                    
            }
        }
    }

    public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser parser = spf.newSAXParser();
        DongleHandler handler = new DongleHandler();

        XMLReader reader = parser.getXMLReader();        
        reader.setContentHandler(handler);
        reader.parse(Test.class.getResource("test.xml").toString());

        Map<String, Dongle> dongles = new HashMap<>();        
        for (Dongle dongle : handler.getDongles()) {
            dongles.put(dongle.name, dongle);
        }

        Scanner sc = new Scanner(System.in);
        System.out.print("Dongle number: ");
        String number = sc.nextLine().trim();
        Dongle dongle = dongles.get(number);
        if (dongle != null) {
            for (Application app : dongle.applications) {
                System.out.println(app.name + " has " + app.attributes.size() + " attributes");
            }
        } else {
            System.out.println("No such dongle");
        }
    }
}
Deine Datei liegt hier einfach als test.xml neben der Test.class.
 

Stiffler

Mitglied
Wenn Du nur einmal etwas aus der Datei lesen willst, könntest Du es mit XPath versuchen. Ansonsten würde ich einen SAXParser bevorzugen, sieht dann in etwa so aus:

Deine Datei liegt hier einfach als test.xml neben der Test.class.

Danke für deine Hilfe :) Wahnsinn es funktioniert.
Nur eine Frage hab ich noch die Attribute werden jetzt ja nur gezählt.
Wenn ich mir die Attribute aber anzeigen lassen möchte muss ich den
Java:
public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser parser = spf.newSAXParser();
        DongleHandler handler = new DongleHandler();

        XMLReader reader = parser.getXMLReader();       
        reader.setContentHandler(handler);
        reader.parse(Test.class.getResource("test.xml").toString());

        Map<String, Dongle> dongles = new HashMap<>();       
        for (Dongle dongle : handler.getDongles()) {
            dongles.put(dongle.name, dongle);
        }

        Scanner sc = new Scanner(System.in);
        System.out.print("Dongle number: ");
        String number = sc.nextLine().trim();
        Dongle dongle = dongles.get(number);
        if (dongle != null) {
            for (Application app : dongle.applications) {
                System.out.println(app.name + " has " + app.attributes.size() + " attributes");
            }
        } else {
            System.out.println("No such dongle");
        }
    }
teil des Codes noch anpassen richtig?
 

mihe7

Top Contributor
Ja, die Attribute werden im Application-Objekt in der Liste attributes gespeichert. Du musst also lediglich darüber iterieren:
Java:
            for (Application app : dongle.applications) {
                System.out.println(app.name);
                for (String attr : app.attributes) {
                    System.out.println("    " + attr);
                }
            }
 

Stiffler

Mitglied
Nun versuche ich schon seit zwei Tagen eine GUI drum herum zu Bauen und verzweifele.

Java:
Scanner sc = new Scanner(System.in);
        System.out.print("Dongle number: ");
        String number = sc.nextLine().trim();
        Dongle dongle = dongles.get(number);
        if (dongle != null) {
            for (Application app : dongle.applications) {
                System.out.println(app.name);
                for (String attr : app.attributes) {
                    System.out.println("    " + attr);
                }
            }
        } else {
            System.out.println("No such dongle");
        }
    }

Eigentlich möchte ich ja nur diesen Teil des Codes in ein JFrame mit einem JNumberfield was die Eingabe der Dongle Number übernehmen soll und eine JTextArea welche mir die Ergebnisse Anzeigen soll. Ich bin glaube echt zu dumm für Java :(
 

mihe7

Top Contributor
Meinst Du sowas?
Java:
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

import java.util.*;
import java.io.*;

import java.awt.BorderLayout;
import java.awt.Font;
import javax.swing.*;

public class Test {
    static class Application {
        private final String name;
        private final List<String> attributes;
    
        public Application(String name, List<String> attributes) {
            this.name = name;
            this.attributes = attributes;
        }
    }

    static class Dongle {
        private final String name;
        private final List<Application> applications;

        public Dongle(String name, List<Application> applications) {
            this.name = name;
            this.applications = applications;
        }
    }

    static class DongleHandler extends DefaultHandler {
        boolean getText = false;
        StringBuilder text;
        String dongleName;
        String applicationName;
        List<String> applicationAttributes = new ArrayList<>();
        List<Application> applications = new ArrayList<>();
        List<Dongle> dongles = new ArrayList<>();

        public List<Dongle> getDongles() { return dongles; }

        public void startElement(String uri, String localName, String qName, 
                Attributes atts) throws SAXException {    
            switch(qName) {
                case "Dongle": 
                    dongleName = atts.getValue("Number"); 
                    applications = new ArrayList<>();
                    break;
                case "Application": 
                    applicationName = atts.getValue("Name");
                    applicationAttributes = new ArrayList<>();
                    break;
                case "Attribute":
                    text = new StringBuilder();
                    getText = true;
                    break;
                default: break;
            }
        }

        public void characters(char[] ch, int start, int length) {
            if (getText) {
                text.append(ch, start, length);
            }
        }

        public void endElement(String uri, String localName, String qName) {
            switch(qName) {
                case "Attribute": 
                    applicationAttributes.add(text.toString());
                    getText = false;
                    break;
                case "Application":
                    applications.add(new Application(applicationName, applicationAttributes));
                    break;
                case "Dongle":
                    dongles.add(new Dongle(dongleName, applications));
                    break;
                    
            }
        }
    }

    private final Map<String, Dongle> dongles;

    public Test(Map<String, Dongle> dongles) {
        this.dongles = dongles;
    }

    public void createAndShowGUI() {
        JTextArea output = new JTextArea(30, 60);
        output.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
        JTextField tf = new JTextField(20);
        tf.addActionListener(e -> {
            String query = tf.getText().trim();
            Dongle dongle = dongles.get(query);
            String text = dongle != null ? dongleToString(dongle) : 
                String.format("Kein Dongle mit Nummer \"%s\" gefunden.\n", query);
            output.setText(text);
        });
        JPanel input = new JPanel();
        input.add(new JLabel("Suche: "));
        input.add(tf);

        JPanel content = new JPanel(new BorderLayout(10,10));
        content.add(input, BorderLayout.NORTH);
        content.add(new JScrollPane(output));

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setContentPane(content);
        frame.pack();
        frame.setVisible(true);    
    }

    private String dongleToString(Dongle dongle) {
        StringBuilder b = new StringBuilder();
        for (Application app : dongle.applications) {
            b.append(app.name).append('\n');
            char[] sep = new char[app.name.length()];
            Arrays.fill(sep, '-');
            b.append(new String(sep)).append('\n');
            for (String attr : app.attributes) {
                b.append(attr).append('\n');
            }
        }
        return b.toString();
    }


    public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser parser = spf.newSAXParser();
        DongleHandler handler = new DongleHandler();

        XMLReader reader = parser.getXMLReader();        
        reader.setContentHandler(handler);
        reader.parse(Test.class.getResource("test.xml").toString());

        Map<String, Dongle> dongles = new HashMap<>();        
        for (Dongle dongle : handler.getDongles()) {
            dongles.put(dongle.name, dongle);
        }

        SwingUtilities.invokeLater(() -> new Test(dongles).createAndShowGUI());
    }
}
Gesucht wird mit der Return-Taste.
 

Stiffler

Mitglied
Hallo @mihe7 ,

nun muss ich das kleine Tool noch ein bisschen weiterführen.
Kannst du mir noch mal unter die Arme greifen? Und es mir vielleicht noch mal erklären?

Ich hab nun noch folgende Anforderungen an das kleine Tool
- bei der Suche müsste aus der *.xml noch die
XML:
<Site ID="0815">
      <Description>000_XXX_123456789</Description>
beiden Elemente durchsucht werden können.
hier stellt sich mir die Frage macht es Sinn da dann eher eine zweite Text Suchzeile zu machen oder beide Suchvarianten in einem Suchfeld abzuarbeiten? Ich glaube aber zwecks der Rückgabe werte (Zahl // Buchstabe) ist das ein Problem oder?
Ich hoffe ich habe das richtig erklärt?

Gruß Steve
 

Stiffler

Mitglied
Bei der Description wäre es glaube ich am sinnvollsten diese Komplett zu durchsuchen da es in der XML Teilweise doppelte Standort namen gibt bzw einem Standort mehrere Dongle IDs zugewiesen sein können.
 

mihe7

Top Contributor
Java:
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

import java.util.*;
import java.io.*;

import java.awt.BorderLayout;
import java.awt.Font;
import javax.swing.*;

public class Test {
    static class Application {
        private final String name;
        private final List<String> attributes;
    
        public Application(String name, List<String> attributes) {
            this.name = name;
            this.attributes = attributes;
        }
    }

    static class Dongle {
        private final String name;
        private final List<Application> applications;

        public Dongle(String name, List<Application> applications) {
            this.name = name;
            this.applications = applications;
        }
    }

    static class Site {
        private final String description;
        private final List<Dongle> dongles;

        public Site(String description, List<Dongle> dongles) {
            this.description = description;
            this.dongles = dongles;
        }
    }

    static class DongleHandler extends DefaultHandler {
        boolean getText = false;
        StringBuilder text;
        String dongleName;
        String applicationName;
        String description;
        List<String> applicationAttributes = new ArrayList<>();
        List<Application> applications = new ArrayList<>();
        List<Dongle> dongles = new ArrayList<>();
        List<Dongle> siteDongles = new ArrayList<>();
        Map<String, List<Dongle>> descriptions = new HashMap<>();

        public List<Dongle> getDongles() { return dongles; }
        public Map<String, List<Dongle>> getDescriptionIndex() { return descriptions; }

        public void startElement(String uri, String localName, String qName, 
                Attributes atts) throws SAXException {    
            switch(qName) {
                case "Site":
                    description = "";
                    siteDongles = new ArrayList<>();
                    break;
                case "Description":
                    text = new StringBuilder();
                    getText = true;
                    break;
                case "Dongle": 
                    dongleName = atts.getValue("Number"); 
                    applications = new ArrayList<>();
                    break;
                case "Application": 
                    applicationName = atts.getValue("Name");
                    applicationAttributes = new ArrayList<>();
                    break;
                case "Attribute":
                    text = new StringBuilder();
                    getText = true;
                    break;
                default: break;
            }
        }

        public void characters(char[] ch, int start, int length) {
            if (getText) {
                text.append(ch, start, length);
            }
        }

        public void endElement(String uri, String localName, String qName) {
            switch(qName) {
                case "Attribute": 
                    applicationAttributes.add(text.toString());
                    getText = false;
                    break;
                case "Application":
                    applications.add(new Application(applicationName, applicationAttributes));
                    break;
                case "Dongle":
                    Dongle dongle = new Dongle(dongleName, applications);
                    dongles.add(dongle);
                    siteDongles.add(dongle);
                    break;
                case "Description":
                    getText = false;
                    description = text.toString();
                    break;
                case "Site":                    
                    descriptions.computeIfAbsent(description, d -> new ArrayList<>())
                            .addAll(siteDongles);
                    break;
            }
        }
    }

    private final Map<String, Dongle> dongles;
    private final Map<String, List<Dongle>> descriptions;

    public Test(Map<String, Dongle> dongles, Map<String, List<Dongle>> descriptions) {
        this.dongles = dongles;
        this.descriptions = descriptions;
    }

    public void createAndShowGUI() {
        JTextArea output = new JTextArea(30, 60);
        output.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
        JTextField tf = new JTextField(20);
        tf.addActionListener(e -> searchForDongles(tf.getText().trim(), output));
        JPanel input = new JPanel();
        input.add(new JLabel("Suche: "));
        input.add(tf);

        JPanel content = new JPanel(new BorderLayout(10,10));
        content.add(input, BorderLayout.NORTH);
        content.add(new JScrollPane(output));

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setContentPane(content);
        frame.pack();
        frame.setVisible(true);    
    }

    private void searchForDongles(String query, JTextArea output) {
        List<Dongle> found = donglesByNumber(query);
        if (found.isEmpty()) {
            found = donglesByDescription(query);
        }

        String text;
        if (found.isEmpty()) {
            text = String.format("Zu \"%s\" wurden keine passenden Dongles gefunden", query);
        } else {
            StringJoiner j = new StringJoiner("\n");
            for (Dongle d : found) {
                j.add(dongleToString(d));
            }
            text = j.toString();
        }
        output.setText(text);
    }

    private List<Dongle> donglesByDescription(String query) {
        List<Dongle> result = new ArrayList<>();
        for (Map.Entry<String, List<Dongle>> entry : descriptions.entrySet()) {
            if (entry.getKey().indexOf(query) != -1) {
                result.addAll(entry.getValue());
            }
        }
        return result;
    }

    private List<Dongle> donglesByNumber(String query) {
        List<Dongle> result = new ArrayList<>();
        Dongle dongle = dongles.get(query);
        if (dongle != null) {
            result.add(dongle);
        }
        return result;
    }

    private String dongleToString(Dongle dongle) {
        StringBuilder b = new StringBuilder();
        for (Application app : dongle.applications) {
            b.append(app.name).append('\n');
            char[] sep = new char[app.name.length()];
            Arrays.fill(sep, '-');
            b.append(new String(sep)).append('\n');
            for (String attr : app.attributes) {
                b.append(attr).append('\n');
            }
        }
        return b.toString();
    }


    public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser parser = spf.newSAXParser();
        DongleHandler handler = new DongleHandler();

        XMLReader reader = parser.getXMLReader();        
        reader.setContentHandler(handler);
        reader.parse(Test.class.getResource("test.xml").toString());

        Map<String, Dongle> dongles = new HashMap<>();        
        for (Dongle dongle : handler.getDongles()) {
            dongles.put(dongle.name, dongle);
        }

        SwingUtilities.invokeLater(() -> new Test(dongles, handler.getDescriptionIndex())
                .createAndShowGUI());
    }
}
 

mihe7

Top Contributor
Java:
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

import java.util.*;
import java.io.*;

import java.awt.BorderLayout;
import java.awt.Font;
import javax.swing.*;

public class Test {
    static class Application {
        private final String name;
        private final List<String> attributes;
    
        public Application(String name, List<String> attributes) {
            this.name = name;
            this.attributes = attributes;
        }
    }

    static class Dongle {
        private final String name;
        private final List<Application> applications;

        public Dongle(String name, List<Application> applications) {
            this.name = name;
            this.applications = applications;
        }
    }

    static class Site {
        private final String description;
        private final List<Dongle> dongles;

        public Site(String description, List<Dongle> dongles) {
            this.description = description;
            this.dongles = dongles;
        }
    }

    static class DongleHandler extends DefaultHandler {
        boolean getText = false;
        StringBuilder text;
        String dongleName;
        String applicationName;
        String description;
        List<String> applicationAttributes = new ArrayList<>();
        List<Application> applications = new ArrayList<>();
        List<Dongle> dongles = new ArrayList<>();
        List<Dongle> siteDongles = new ArrayList<>();
        Map<String, List<Dongle>> descriptions = new HashMap<>();

        public List<Dongle> getDongles() { return dongles; }
        public Map<String, List<Dongle>> getDescriptionIndex() { return descriptions; }

        public void startElement(String uri, String localName, String qName, 
                Attributes atts) throws SAXException {    
            switch(qName) {
                case "Site":
                    description = "";
                    siteDongles = new ArrayList<>();
                    break;
                case "Description":
                    text = new StringBuilder();
                    getText = true;
                    break;
                case "Dongle": 
                    dongleName = atts.getValue("Number"); 
                    applications = new ArrayList<>();
                    break;
                case "Application": 
                    applicationName = atts.getValue("Name");
                    applicationAttributes = new ArrayList<>();
                    break;
                case "Attribute":
                    text = new StringBuilder();
                    getText = true;
                    break;
                default: break;
            }
        }

        public void characters(char[] ch, int start, int length) {
            if (getText) {
                text.append(ch, start, length);
            }
        }

        public void endElement(String uri, String localName, String qName) {
            switch(qName) {
                case "Attribute": 
                    applicationAttributes.add(text.toString());
                    getText = false;
                    break;
                case "Application":
                    applications.add(new Application(applicationName, applicationAttributes));
                    break;
                case "Dongle":
                    Dongle dongle = new Dongle(dongleName, applications);
                    dongles.add(dongle);
                    siteDongles.add(dongle);
                    break;
                case "Description":
                    getText = false;
                    description = text.toString();
                    break;
                case "Site":                    
                    descriptions.computeIfAbsent(description, d -> new ArrayList<>())
                            .addAll(siteDongles);
                    break;
            }
        }
    }

    private final Map<String, Dongle> dongles;
    private final Map<String, List<Dongle>> descriptions;

    public Test(Map<String, Dongle> dongles, Map<String, List<Dongle>> descriptions) {
        this.dongles = dongles;
        this.descriptions = descriptions;
    }

    public void createAndShowGUI() {
        JTextArea output = new JTextArea(30, 60);
        output.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
        JTextField tf = new JTextField(20);
        tf.addActionListener(e -> searchForDongles(tf.getText().trim(), output));
        JPanel input = new JPanel();
        input.add(new JLabel("Suche: "));
        input.add(tf);

        JPanel content = new JPanel(new BorderLayout(10,10));
        content.add(input, BorderLayout.NORTH);
        content.add(new JScrollPane(output));

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setContentPane(content);
        frame.pack();
        frame.setVisible(true);    
    }

    private void searchForDongles(String query, JTextArea output) {
        Map<String, List<Dongle>> found = donglesByNumber(query);
        if (found.isEmpty()) {
            found = donglesByDescription(query);
        }

        String text = "";
        if (found.isEmpty()) {
            text = String.format("Zu \"%s\" wurden keine passenden Dongles gefunden", query);
        } else {
            for (Map.Entry<String,List<Dongle>> entry : found.entrySet()) {
                String description = entry.getKey();
                StringJoiner j = new StringJoiner("\n");
                for (Dongle d : entry.getValue()) {
                    j.add(dongleToString(d, description));
                }
                text = j.toString();
            }
        }
        output.setText(text);
    }

    private Map<String, List<Dongle>> donglesByDescription(String query) {
        Map<String, List<Dongle>> result = new HashMap<>();
        for (Map.Entry<String, List<Dongle>> entry : descriptions.entrySet()) {
            String description = entry.getKey();
            if (description.indexOf(query) != -1) {
                result.put(description, entry.getValue());
            }
        }
        return result;
    }

    private Map<String, List<Dongle>> donglesByNumber(String query) {
        Map<String, List<Dongle>> result = new HashMap<>();
        Dongle dongle = dongles.get(query);
        if (dongle != null) {
            result.put("", Collections.singletonList(dongle));
        }
        return result;
    }

    private String dongleToString(Dongle dongle, String description) {
        StringBuilder b = new StringBuilder();
        if (!description.isEmpty()) {
            b.append("Description: ").append(description).append('\n');
        }
            
        for (Application app : dongle.applications) {
            b.append(app.name).append('\n');
            char[] sep = new char[app.name.length()];
            Arrays.fill(sep, '-');
            b.append(new String(sep)).append('\n');
            for (String attr : app.attributes) {
                b.append(attr).append('\n');
            }
        }
        return b.toString();
    }


    public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser parser = spf.newSAXParser();
        DongleHandler handler = new DongleHandler();

        XMLReader reader = parser.getXMLReader();        
        reader.setContentHandler(handler);
        reader.parse(Test.class.getResource("test.xml").toString());

        Map<String, Dongle> dongles = new HashMap<>();        
        for (Dongle dongle : handler.getDongles()) {
            dongles.put(dongle.name, dongle);
        }

        SwingUtilities.invokeLater(() -> new Test(dongles, handler.getDescriptionIndex())
                .createAndShowGUI());
    }
}
 

Stiffler

Mitglied
Die Suche findet immer nur ein Ergebnis richtig? Oder kann die Suche auch mehrere Ergebnisse finden? Wenn zum Beispiel zwei mal in der XML im abschnitt Description 2 mal "Leipzig" vorkommt listet die suche nur einmal auf. Quasi müsste man noch so eine Art weitersuchen machen? Der Parser geht ja von oben nach unten und hört auf sobald er ein Ergebnis gefunden hat auf?
 

mihe7

Top Contributor
Die Suche findet immer nur ein Ergebnis richtig? Oder kann die Suche auch mehrere Ergebnisse finden? Wenn zum Beispiel zwei mal in der XML im abschnitt Description 2 mal "Leipzig" vorkommt listet die suche nur einmal auf.
Kleiner Fehler. Verwende die Methode:
Java:
    private void searchForDongles(String query, JTextArea output) {
        Map<String, List<Dongle>> found = donglesByNumber(query);
        if (found.isEmpty()) {
            found = donglesByDescription(query);
        }

        String text = "";
        if (found.isEmpty()) {
            text = String.format("Zu \"%s\" wurden keine passenden Dongles gefunden", query);
        } else {
            StringJoiner j = new StringJoiner("\n");
            for (Map.Entry<String,List<Dongle>> entry : found.entrySet()) {
                String description = entry.getKey();
                for (Dongle d : entry.getValue()) {
                    j.add(dongleToString(d, description));
                }
            }
            text = j.toString();
        }
        output.setText(text);
    }
 

Stiffler

Mitglied
Ich stehe schon wieder vor der völligen Verzweiflung :eek:
Wenn ich in der Suche nun nach der Description Suche Listet es mir ja auch die Description mit auf. Soweit so gut.
Nun wollte ich einfach nur bei der DongleNummer Suche auch das mir die Description mit ausgegeben wird.

Entweder schaffe ich es das der Code gar nicht mehr funktioniert oder er funktioniert zeigt mir aber nicht das gewünschte Ergebnis.
Java:
 private void searchForDongles(String query, JTextArea output) {
        Map<String, List<Dongle>> found = donglesByNumber(query);
        if (found.isEmpty()) {
            found = donglesByDescription(query);
        }

        String text = "";
        if (found.isEmpty()) {
            text = String.format("Zu \"%s\" wurden keine passenden Dongles gefunden", query);
        } else {
            StringJoiner j = new StringJoiner("\n");
            for (Map.Entry<String,List<Dongle>> entry : found.entrySet()) {
                String description = entry.getKey();
                for (Dongle d : entry.getValue()) {
                    j.add(dongleToString(d, description));
                }
            }
            text = j.toString();
        }
        output.setText(text);
    }

Von meinem Verständnis her muss ich doch in diesem Teil des Codes noch die Variable hinzufügen richtig?
 

Stiffler

Mitglied
Wenn sie aufgelistet wird, dann wird sie doch bereits ausgegeben.
Wenn ich per Texteingabe suche "Leipzig" zum beispiel Listet mir die Suche die Description mit auf.
Suche jedoch nach einer Dongle Nummer, bekomme ich nur die Anzeige der Dongle // Application // Attribute - bei dieser Suchvariante wäre es aber auch gut die Description mit angezeigt zu bekommen da in der Description die Standort mit drin stehen und man so eine Dongle Nummer dem Standort direkt zuteilen kann.

Umständlich ich weis .... o_O
 

mihe7

Top Contributor
Ja, das liegt daran, dass bei donglesByNumber keine Description gesetzt wird. In der main-Methode werden die IDs auf Dongles abgebildet. Dongles haben habe keine Beschreibung, weil die in der Site steckt. Das müsstest Du entsprechend anpassen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L invalide xml document parsen?! XML & JSON 2
L XML Document Transform StackOverflowError XML & JSON 1
B Wie kann man das ecncoding in einem vorhandenen Document-Objekt ändern? XML & JSON 2
M java.lang.RuntimeException: Failed to parse document XML & JSON 4
sylo DOM Document in XML Datei schreiben XML & JSON 5
sambalmueslie JAXB - Unmarshall ein XML-Document das aus zwei XSD Definitionen besteht XML & JSON 8
G Nodes in Document kopieren, nur die Childs, die noch nicht existieren XML & JSON 7
K Document null bei builder.parse XML & JSON 2
B jdom document aus string erzeugen? XML & JSON 1
G document is invalid: no grammar found. XML & JSON 9
M Wie kann ich aus ein Document-Tree ein PDF generieren XML & JSON 2
G Ein DOM-Document dem Sax übergeben? XML & JSON 2
S org.jdom.document in String umwandeln. XML & JSON 2
P Aus einem Node ein Document erstellen XML & JSON 2
R XML Document als String XML & JSON 2
C Kompliziertes XML-Document, wie lese ich es ein? XML & JSON 4
N FileStream auf Document XML & JSON 22
M XPath Problem im Zusammenhang mit document() XML & JSON 2
B XML-Document mit Java erzeugen und zuruecksenden XML & JSON 1
W XML-Document auslesen XML & JSON 2
MiMa Buch Metadaten aus XML Datei parsen XML & JSON 48
M parsen von realen HTML-WEB-Seiten XML & JSON 1
MiMa parsen mit regex -> ein schnelles Ende XML & JSON 10
K Beim Parsen einer XML-Datei Connection timed out XML & JSON 4
F Parsen von Daten aus einer Homepage XML & JSON 6
G Langsam beim SAX-Parsen - woran liegts? XML & JSON 2
C Parsen des XML-Streams mit SAX XML & JSON 3
M XML Datei Parsen XML & JSON 4
D SAX parsen - Wie? XML & JSON 11
S XML Parsen und Werte zwischenspeichern XML & JSON 2
K Kurze XML Datei Parsen XML & JSON 5
whitenexx Problem beim parsen von Facebook XML XML & JSON 3
J Comments in XML parsen XML & JSON 3
H Nicht wohlgeformtes XML mit SAX parsen XML & JSON 2
M XML Parsen JDOM NullPointerEcxeption XML & JSON 7
Z XML parsen - Element mit Werten XML & JSON 2
ruutaiokwu xml nur bis auf eine bestimmte ebene parsen mit javax.xml... XML & JSON 5
L [SAX] Geschachtelte XML Datei parsen XML & JSON 3
R XML in UTF-8 mit SAX parsen XML & JSON 9
O Parsen einer XML mit JDOM ohne Doctype Declaration XML & JSON 2
F Probleme beim html parsen mit tagsoup XML & JSON 4
M Probleme beim Parsen eines gefilterten XML-Dokuments XML & JSON 6
Semox Kann JUnit XML Parsen? XML & JSON 2
L Reihenfolge beim xml Datei parsen einhalten? XML & JSON 8
L xml Datei parsen ohne End-Tag XML & JSON 6
T RSS-Feed parsen und in Datenbank speichern XML & JSON 6
B XML parsen XML & JSON 3
H XML parsen und unbekannten Namespace zurückgeben XML & JSON 5
S DOM Parsen Problem mit HTML Sonderzeichen XML & JSON 4
ABstraCT XML properties am einfachsten parsen. XML & JSON 2
U xmi parsen über emf XML & JSON 10
S XML-Schema einlesen um parsen zu erleichtern? XML & JSON 2
T Problem beim Parsen von Attribut xmlns="urn:com:test&qu XML & JSON 6
P XMLGregorianCalender parsen XML & JSON 4
M Datei parsen XML & JSON 5
S HTML mit dom4j parsen? XML & JSON 2
X XML File auslesen/parsen u. in ne Hashmap speichern XML & JSON 2
Saxony unbekannte XML Datei parsen und ausgeben XML & JSON 10
P "Formatierungs-Tags" parsen XML & JSON 3
M Attribute parsen XML & JSON 6
R Parsen einer XML ohne Validierung XML & JSON 2
D XML Datei innerhalb einer JAR Datei parsen XML & JSON 2
M Xerces -Parsen mit einer externen Schemadatei geht nicht XML & JSON 2
L bz2-Datei parsen XML & JSON 9
K XML parsen Whitespaces XML & JSON 2
I XML-String mit SAX parsen ? XML & JSON 2
M Object in XML parsen XML & JSON 2
byte Probleme beim Parsen von XHTML-Datei XML & JSON 4
P HTML Seite Parsen, und bestimmten Text extrahieren XML & JSON 3
X xml und xsl parsen mit xerces XML & JSON 8
W Xml-String parsen XML & JSON 2
W root element parsen,Hilfe! XML & JSON 5
F Gibt es Möglichkeiten Deutsche Sätze zu parsen ? XML & JSON 2
A Auf der Suche nach Bibliotheken oder wie parsen? XML & JSON 15
S XML Datei mit Schemafehler parsen XML & JSON 14
R StreamSource parsen ! XML & JSON 8
R RSS parsen XML & JSON 2
K XML Datei parsen XML & JSON 4
S CSV Datei einlesen und XML Ausgeben XML & JSON 2
S NodeList rückwärts scannen, alle Parent Nodes ausgeben rekursiv und nicht-reukrsiv XML & JSON 0
N Zusammenfassung ausgeben XML & JSON 2
C JAXB: XML-Elemente einlesen und als XML-Attribute ausgeben XML & JSON 7
T Xpath & JDOM Element Pfad ausgeben XML & JSON 2
R Element - Ausgeben von Kommentar XML & JSON 4
S XML einlesen, analysieren, bearbeiten & als Textdatei ausgeben XML & JSON 1
D ID's aus XML Datei rauslesen und in Java ausgeben XML & JSON 7
E XML Datei einlesen und Elemente in der Console ausgeben XML & JSON 6
B XML-Element als String ausgeben XML & JSON 5
C Kompletten Inhalt eines Tags ausgeben XML & JSON 2
ARadauer XML formatiert ausgeben XML & JSON 4
Blackmore Atribute in Console ausgeben XML & JSON 3
F XML in PDF ausgeben. XML & JSON 2
G XML mit JDOM ausgeben [Klappe die 1Mio.ste] XML & JSON 2
A XML-file an der Konsole ausgeben XML & JSON 4
A XML-File ausgeben XML & JSON 2
G Aus XML-Datei auslesen und als Java-Dialog ausgeben XML & JSON 3

Ähnliche Java Themen

Neue Themen


Oben