C-lara
C-lara

Reputation: 115

How to create an area?

import java.io.File;
import java.io.IOException;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

public class ReadXMLFile {
public static void main(String[] args) {

  SAXBuilder builder = new SAXBuilder();
  File xmlFile = new File("c:\\test.xml");

  try {

    Document document = (Document) builder.build(xmlFile);
    Element rootNode = document.getRootElement();
    List list = rootNode.getChildren("raum");

    for (int i = 0; i < list.size(); i++) {

       Element node = (Element) list.get(i);

       System.out.println("ID : " + node.getChildText("ID"));

    }

  } catch (IOException io) {
    System.out.println(io.getMessage());
  } catch (JDOMException jdomex) {
    System.out.println(jdomex.getMessage());
  }
}

}

I don't understand how the step in between has to look like in order to insert the imported coordinates into the polygon.. Maybe someone can help me with this?

Upvotes: 1

Views: 111

Answers (3)

Abra
Abra

Reputation: 20914

For the sake of completeness?
This is how to achieve it using SAX parser.
Note that it is not clear to me, from your question, which Polygon you are referring to. I presume it is a java class. It can't be java.awt.Polygon because its points are all int whereas your sample XML file contains only double values. The only other class I thought of was javafx.scene.shape.Polygon that contains an array of points where each point is a double. Hence in the below code, I create an instance of javafx.scene.shape.Polygon.

For the situation you describe in your question, I don't see the point (no pun intended) in loading the entire DOM tree into memory. You simply need to create a point every time you encounter a x and a y coordinate in the XML file and add those coordinates to a collection of points.

Here is the code. Note that I created an XML file named polygon0.xml that contains the entire XML from your question. Also note that you can extend class org.xml.sax.helpers.DefaultHandler rather than implement interface ContentHandler.

import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import javafx.scene.shape.Polygon;

public class Polygons implements ContentHandler {
    private boolean isX;
    private boolean isY;
    private Polygon polygon;
/* Start 'ContentHandler' interface methods. */
    @Override // org.xml.sax.ContentHandler
    public void setDocumentLocator(Locator locator) {
        // Do nothing.
    }

    @Override // org.xml.sax.ContentHandler
    public void startDocument() throws SAXException {
        polygon = new Polygon();
    }

    @Override // org.xml.sax.ContentHandler
    public void endDocument() throws SAXException {
        // Do nothing.
    }

    @Override // org.xml.sax.ContentHandler
    public void startPrefixMapping(String prefix, String uri) throws SAXException {
        // Do nothing.
    }

    @Override // org.xml.sax.ContentHandler
    public void endPrefixMapping(String prefix) throws SAXException {
        // Do nothing.
    }

    @Override // org.xml.sax.ContentHandler
    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
        isX = "x".equals(qName);
        isY = "y".equals(qName);
    }

    @Override // org.xml.sax.ContentHandler
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (isX) {
            isX = false;
        }
        if (isY) {
            isY = false;
        }
    }

    @Override // org.xml.sax.ContentHandler
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (isX || isY) {
            StringBuilder sb = new StringBuilder(length);
            int end = start + length;
            for (int i = start; i < end; i++) {
                sb.append(ch[i]);
            }
            polygon.getPoints().add(Double.parseDouble(sb.toString()));
        }
    }

    @Override // org.xml.sax.ContentHandler
    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
        // Do nothing.
    }

    @Override // org.xml.sax.ContentHandler
    public void processingInstruction(String target, String data) throws SAXException {
        // Do nothing.
    }

    @Override // org.xml.sax.ContentHandler
    public void skippedEntity(String name) throws SAXException {
        // Do nothing.
    }
/* End 'ContentHandler' interface methods. */
    public static void main(String[] args) {
        Polygons instance = new Polygons();
        Path path = Paths.get("polygon0.xml");
        SAXParserFactory spf = SAXParserFactory.newInstance();
        try (FileReader reader = new FileReader(path.toFile())) { // throws java.io.IOException
            SAXParser saxParser = spf.newSAXParser(); // throws javax.xml.parsers.ParserConfigurationException , org.xml.sax.SAXException
            XMLReader xmlReader = saxParser.getXMLReader(); // throws org.xml.sax.SAXException
            xmlReader.setContentHandler(instance);
            InputSource input = new InputSource(reader);
            xmlReader.parse(input);
            System.out.println(instance.polygon);
        }
        catch (IOException                  |
               ParserConfigurationException |
               SAXException x) {
            x.printStackTrace();
        }
    }
}

Here is the output from running the above code:

Polygon[points=[400.3, 997.2, 400.3, 833.1, 509.9, 833.1, 509.9, 700.0, 242.2, 700.0, 242.2, 600.1, 111.1, 600.1, 111.1, 300.0, 300.0, 300.0, 300.0, 420.0, 600.5, 420.0, 600.5, 101.9, 717.8, 101.9, 717.8, 200.0, 876.5, 200.0, 876.5, 500.8, 1012.1, 500.8, 1012.1, 900.2, 902.0, 900.2, 902.0, 997.2], fill=0x000000ff]

EDIT

As requested, by OP, here is an implementation using JDOM (version 2.0.6)

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.filter.ElementFilter;
import org.jdom2.input.SAXBuilder;
import org.jdom2.util.IteratorIterable;

import javafx.scene.shape.Polygon;

public class Polygon2 {
    public static void main(String[] args) {
        Polygon polygon = new Polygon();
        Path path = Paths.get("polygon0.xml");
        SAXBuilder builder = new SAXBuilder();
        try {
            Document jdomDoc = builder.build(path.toFile()); // throws java.io.IOException , org.jdom2.JDOMException
            Element root = jdomDoc.getRootElement();
            IteratorIterable<Element> iter = root.getDescendants(new ElementFilter("edge"));
            while (iter.hasNext()) {
                Element elem = iter.next();
                Element childX = elem.getChild("x");
                polygon.getPoints().add(Double.parseDouble(childX.getText()));
                Element childY = elem.getChild("y");
                polygon.getPoints().add(Double.parseDouble(childY.getText()));
            }
        }
        catch (IOException | JDOMException x) {
            x.printStackTrace();
        }
        System.out.println(polygon);
    }
}

Upvotes: 1

Alisher
Alisher

Reputation: 940

You can read XML files DOM parser library check this article.

I assume you are working on a Desktop application so you might want to use FileChooser for file selection. Here is an example of this.

Also, I think you would need to make some structural changes (for convinience) to your XML file so that it would have something like this:

<xpoints>
 <x>5<x/>
...
</xpoints>
<ypoints>
 <y>5<y/>
...
</ypoints>

But for existing structure doing something like this would be enogh:

    File file = new File("file");
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(file);
    doc.getDocumentElement().normalize();
    NodeList nodeList = doc.getElementsByTagName("edge");
// you can iterate over all edges
    for (int itr = 0; itr < nodeList.getLength(); itr++)
    {
      Node node = nodeList.item(itr);
      if (node.getNodeType() == Node.ELEMENT_NODE)
      {
        Element eElement = (Element) node;

//then you can access values, for example, to pass them to an array
        array.add(eElement.getElementsByTagName("x").item(0).getTextContent()));

      }
    }

Upvotes: 1

Nithin
Nithin

Reputation: 703

You can follow any sample JDOM parser example and do it. For example, this explains how to read the xml and take the data in a list and iterate over it. Just follow the steps and understand what you are doing, you can easily get it done.

Upvotes: 2

Related Questions