Reputation: 115
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
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]
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
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