Are there any examples of using the new GraphMLReader and GraphMLWriter?
I need to write my graph to a file, but i also need to store it's other attributes too.
Not sure where to start.
Thanks in advance,
-J
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think There is a problem with the sax "character" override inside GraphMLReader, for some reason some of my strings come in truncated and then the rest of the string comes in on the next character call (before the endElement is called).
To finish handling the content events, you need to handle the characters that the parser delivers to your application.
Parsers are not required to return any particular number of characters at one time. A parser can return anything from a single character at a time up to several thousand and still be a standard-conforming implementation. So if your application needs to process the characters it sees, it is wise to accumulate the characters in a buffer and operate on them only when you are sure that all of them have been found.
Here is a patch for GraphMLReader.java if you are interested in using it. I just moved some of the code around so that the "Character" override appends the text until it gets to the end element. This will correct the issue where the parser only send part of the data in the first character call and then sends the rest of the characters in the subsequent calls.
Jay,
I'm not sure exactly what input you were using that caused the issue with the SAX characters, but would you mind trying the same test with the proposed GraphMLReader2 in CVS: (http://jung.cvs.sourceforge.net/jung/jung2/jung-io/src/main/java/edu/uci/ics/jung/io/graphml/GraphMLReader2.java?view=markup)
It would be a shame to get this bug fixed in one of the reader classes and not the other :)
Thanks,
Nate
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I actually switched over to the GraphMLReader2 because it was easier to get the data into my classes. The GraphMLReader2 works perfectly. The issue i was having with the normal GraphMLReader was due to the sax "Characters" override method only delivering small chunks of data at a time, i don't think your using that override in the GraphMLReader2.
I was wrong, your GraphML reader exhibits the same behaivor as the normal Jung version. I just tried processing a larger XML document today and had the same problem. The string was only a few hundered characters, but i was only receiving the last 8 or so.
The problem occurs at line 72 in DataElementParser.java
if (event.isCharacters()) {
Characters characters = (Characters) event;
data.setValue(characters.getData());
}
The characters.getData() needs to be appended to a StringBuffer until the endtag is reached.
-J
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Jay,
Good catch! Do you have a particular input file that will cause the problem? We should probably add a unit test to verify that the problem is resolved going forward.
Regards,
Nate
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am encountering some errors with the GraphMLReader (and maybe the writer too)... I am not really an experienced programmer, so maybe I am making some basic mistakes or maybe I am encountering a similar problem as described above, but I don’t understand it completely.
What I want to do is to save a graph in one program and open/ use it in another one. My code:
Program one:
GraphMLWriter gw = new GraphMLWriter();
FileWriter outputFileReader = new FileWriter("TEST.xml");
gw.save(g, outputFileReader);
Program two:
Graph g = new SparseGraph<City, String>();
GraphMLReader gr = new GraphMLReader();
String directory = "C…";
FileReader inputFileReader = new FileReader(directory+ "TEST.xml");
gr.load(inputFileReader, g);
By doing this I get the following error:
java.lang.IllegalArgumentException: If no edge factory is supplied, edge id may not be null: {source=WUH, directed=false, target=KHN}
at edu.uci.ics.jung.io.GraphMLReader.createEdge(GraphMLReader.java:677)
at edu.uci.ics.jung.io.GraphMLReader.startElement(GraphMLReader.java:282)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)
at …
Am I doing something wrong or has this something to do with the problem described? And is there an "easy" solution for this?
Thank you in advance,
Wim
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Are there any examples of using the new GraphMLReader and GraphMLWriter?
I need to write my graph to a file, but i also need to store it's other attributes too.
Not sure where to start.
Thanks in advance,
-J
Nevermind, i think i got it figured out.
Actually, if anyone has an example of using an GraphMLReader to get the "data" back into the vertices, that would help.
Thanks in advance,
-J
Jay:
Take a look at the GraphML unit tests.
Joshua
hi -- ok its my day for not being able to find things, but where ARE the unit tests for this? cant find them in any of the source distro...?
thanks
The test are located here:
C:\src\jung2\jung-io\src\test\java\edu\uci\ics\jung\io
The unit tests for the jung-io module are under src/test/java (the standard location for Maven).
FYI - As it looks now, the unit tests for the newly proposed GraphML parser haven't been checked in yet.
I think There is a problem with the sax "character" override inside GraphMLReader, for some reason some of my strings come in truncated and then the rest of the string comes in on the next character call (before the endElement is called).
After some research i found this is by design:
----FROM http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JAXPSAX3.html----------------------
Character Events
To finish handling the content events, you need to handle the characters that the parser delivers to your application.
Parsers are not required to return any particular number of characters at one time. A parser can return anything from a single character at a time up to several thousand and still be a standard-conforming implementation. So if your application needs to process the characters it sees, it is wise to accumulate the characters in a buffer and operate on them only when you are sure that all of them have been found.
------------------------------------------------------------------------------------
So i think the character call just needs to keep appending the string, and the actual string processing need to happen at the endElement call.
Does this sound right, or am i doing something wrong?
-J
found now
thanks
d
Here is a patch for GraphMLReader.java if you are interested in using it. I just moved some of the code around so that the "Character" override appends the text until it gets to the end element. This will correct the issue where the parser only send part of the data in the first character call and then sends the rest of the characters in the subsequent calls.
-J
Index: GraphMLReader.java
RCS file: /cvsroot/jung/jung2/jung-io/src/main/java/edu/uci/ics/jung/io/GraphMLReader.java,v
retrieving revision 1.9
diff -u -r1.9 GraphMLReader.java
--- GraphMLReader.java 20 Jul 2008 22:32:27 -0000 1.9
+++ GraphMLReader.java 5 Aug 2008 13:40:08 -0000
@@ -96,6 +96,7 @@
protected List<G> graphs;
+ protected StringBuffer textBuffer;
/**
* Creates a <code>GraphMLReader</code> instance with the specified
* vertex and edge factories.
@@ -233,6 +234,9 @@
@Override
public void startElement(String uri, String name, String qName, Attributes atts) throws SAXNotSupportedException
{
+ //If we got a new element, we prob want to discard the textBuffer
+ textBuffer = null;
+
String tag = qName.toLowerCase();
TagState state = tag_state.get(tag);
if (state == null)
@@ -374,103 +378,116 @@
@Override
- public void characters(char[] ch, int start, int length) throws SAXNotSupportedException
+ public void characters(char[] ch, int start, int length) throws SAXException
{
- String text = new String(ch, start, length);
-
- switch (this.current_states.getFirst())
- {
- case DESC:
- switch (this.current_states.get(1)) // go back one
- {
- case GRAPH:
- graph_desc.put(current_graph, text);
- break;
- case VERTEX:
- case ENDPOINT:
- vertex_desc.put(current_vertex, text);
- break;
- case EDGE:
- case HYPEREDGE:
- edge_desc.put(current_edge, text);
- break;
- case DATA:
- switch (key_type)
- {
- case GRAPH:
- graph_metadata.get(current_key).description = text;
- break;
- case VERTEX:
- vertex_metadata.get(current_key).description = text;
- break;
- case EDGE:
- edge_metadata.get(current_key).description = text;
- break;
- case ALL:
- graph_metadata.get(current_key).description = text;
- vertex_metadata.get(current_key).description = text;
- edge_metadata.get(current_key).description = text;
- break;
- default:
- throw new SAXNotSupportedException("Invalid key type" +
- " specified for default: " + key_type);
- }
-
- break;
- default:
- break;
- }
- break;
- case DATA:
- switch (this.current_states.get(1))
- {
- case GRAPH:
- addDatum(graph_metadata, current_graph, text);
- break;
- case VERTEX:
- case ENDPOINT:
- addDatum(vertex_metadata, current_vertex, text);
- break;
- case EDGE:
- case HYPEREDGE:
- addDatum(edge_metadata, current_edge, text);
- break;
- default:
- break;
- }
- break;
- case DEFAULT_KEY:
- if (this.current_states.get(1) != TagState.KEY)
- throw new SAXNotSupportedException("'default' only defined in context of 'key' tag: " +
- "stack: " + current_states.toString());
-
- switch (key_type)
- {
- case GRAPH:
- graph_metadata.get(current_key).default_value = text;
- break;
- case VERTEX:
- vertex_metadata.get(current_key).default_value = text;
- break;
- case EDGE:
- edge_metadata.get(current_key).default_value = text;
- break;
- case ALL:
- graph_metadata.get(current_key).default_value = text;
- vertex_metadata.get(current_key).default_value = text;
- edge_metadata.get(current_key).default_value = text;
- break;
- default:
- throw new SAXNotSupportedException("Invalid key type" +
- " specified for default: " + key_type);
- }
-
- break;
- default:
- break;
- }
+ String s = new String(ch, start, length);
+ if (textBuffer == null)
+ {
+ textBuffer = new StringBuffer(s);
+ }
+ else
+ {
+ textBuffer.append(s);
+ }
+ }
+
+ private void processStringData(String textData) throws SAXNotSupportedException
+ {
+
+ switch (this.current_states.getFirst())
+ {
+ case DESC:
+ switch (this.current_states.get(1)) // go back one
+ {
+ case GRAPH:
+ graph_desc.put(current_graph, textData);
+ break;
+ case VERTEX:
+ case ENDPOINT:
+ vertex_desc.put(current_vertex, textData);
+ break;
+ case EDGE:
+ case HYPEREDGE:
+ edge_desc.put(current_edge, textData);
+ break;
+ case DATA:
+ switch (key_type)
+ {
+ case GRAPH:
+ graph_metadata.get(current_key).description = textData;
+ break;
+ case VERTEX:
+ vertex_metadata.get(current_key).description = textData;
+ break;
+ case EDGE:
+ edge_metadata.get(current_key).description = textData;
+ break;
+ case ALL:
+ graph_metadata.get(current_key).description = textData;
+ vertex_metadata.get(current_key).description = textData;
+ edge_metadata.get(current_key).description = textData;
+ break;
+ default:
+ throw new SAXNotSupportedException("Invalid key type" +
+ " specified for default: " + key_type);
+ }
+
+ break;
+ default:
+ break;
+ }
+ break;
+ case DATA:
+ switch (this.current_states.get(1))
+ {
+ case GRAPH:
+ addDatum(graph_metadata, current_graph, textData);
+ break;
+ case VERTEX:
+ case ENDPOINT:
+ addDatum(vertex_metadata, current_vertex, textData);
+ break;
+ case EDGE:
+ case HYPEREDGE:
+ addDatum(edge_metadata, current_edge, textData);
+ break;
+ default:
+ break;
+ }
+ break;
+ case DEFAULT_KEY:
+ if (this.current_states.get(1) != TagState.KEY)
+ throw new SAXNotSupportedException("'default' only defined in context of 'key' tag: " +
+ "stack: " + current_states.toString());
+
+ switch (key_type)
+ {
+ case GRAPH:
+ graph_metadata.get(current_key).default_value = textData;
+ break;
+ case VERTEX:
+ vertex_metadata.get(current_key).default_value = textData;
+ break;
+ case EDGE:
+ edge_metadata.get(current_key).default_value = textData;
+ break;
+ case ALL:
+ graph_metadata.get(current_key).default_value = textData;
+ vertex_metadata.get(current_key).default_value = textData;
+ edge_metadata.get(current_key).default_value = textData;
+ break;
+ default:
+ throw new SAXNotSupportedException("Invalid key type" +
+ " specified for default: " + key_type);
+ }
+
+ break;
+ default:
+ break;
+ }
}
-
+
+
protected <T>void addDatum(Map<String, GraphMLMetadata<T>> metadata,
T current_elt, String text) throws SAXNotSupportedException
{
@@ -488,6 +505,11 @@
@Override
public void endElement(String uri, String name, String qName) throws SAXNotSupportedException
{
+ if(textBuffer != null)
+ {
+ processStringData(textBuffer.toString());
+ textBuffer = null;
+ }
String tag = qName.toLowerCase();
TagState state = tag_state.get(tag);
if (state == null)
Jay,
I'm not sure exactly what input you were using that caused the issue with the SAX characters, but would you mind trying the same test with the proposed GraphMLReader2 in CVS: (http://jung.cvs.sourceforge.net/jung/jung2/jung-io/src/main/java/edu/uci/ics/jung/io/graphml/GraphMLReader2.java?view=markup)
It would be a shame to get this bug fixed in one of the reader classes and not the other :)
Thanks,
Nate
I actually switched over to the GraphMLReader2 because it was easier to get the data into my classes. The GraphMLReader2 works perfectly. The issue i was having with the normal GraphMLReader was due to the sax "Characters" override method only delivering small chunks of data at a time, i don't think your using that override in the GraphMLReader2.
Here is more info on the characters method if interested: http://java.sun.com/j2se/1.5.0/docs/api/org/xml/sax/ContentHandler.html#characters\(char[],%20int,%20int)
Thanks for the help. GraphMLReader2 works great!
Cheers,
-J
Great - glad to hear it!
Cheers,
Nate
Nate,
I was wrong, your GraphML reader exhibits the same behaivor as the normal Jung version. I just tried processing a larger XML document today and had the same problem. The string was only a few hundered characters, but i was only receiving the last 8 or so.
The problem occurs at line 72 in DataElementParser.java
if (event.isCharacters()) {
Characters characters = (Characters) event;
data.setValue(characters.getData());
}
The characters.getData() needs to be appended to a StringBuffer until the endtag is reached.
-J
Hi Jay,
Good catch! Do you have a particular input file that will cause the problem? We should probably add a unit test to verify that the problem is resolved going forward.
Regards,
Nate
Hello,
I am encountering some errors with the GraphMLReader (and maybe the writer too)... I am not really an experienced programmer, so maybe I am making some basic mistakes or maybe I am encountering a similar problem as described above, but I don’t understand it completely.
What I want to do is to save a graph in one program and open/ use it in another one. My code:
Program one:
GraphMLWriter gw = new GraphMLWriter();
FileWriter outputFileReader = new FileWriter("TEST.xml");
gw.save(g, outputFileReader);
Program two:
Graph g = new SparseGraph<City, String>();
GraphMLReader gr = new GraphMLReader();
String directory = "C…";
FileReader inputFileReader = new FileReader(directory+ "TEST.xml");
gr.load(inputFileReader, g);
By doing this I get the following error:
java.lang.IllegalArgumentException: If no edge factory is supplied, edge id may not be null: {source=WUH, directed=false, target=KHN}
at edu.uci.ics.jung.io.GraphMLReader.createEdge(GraphMLReader.java:677)
at edu.uci.ics.jung.io.GraphMLReader.startElement(GraphMLReader.java:282)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)
at …
Am I doing something wrong or has this something to do with the problem described? And is there an "easy" solution for this?
Thank you in advance,
Wim