anderspitman / graphml-js

GraphML parser for javascript
MIT License
12 stars 2 forks source link

Empty edge is allowed by GraphML spec but graphml-js can't parse a graph with no edge. #6

Closed shinnya closed 7 years ago

shinnya commented 7 years ago

graphml-js can't parse a graph which has no edge and reports the following error:

$ cat index.js
var graphml = require('graphml-js')
  , fs      = require('fs');

var content = fs.readFileSync('./graph.xml');
var parser  = new graphml.GraphMLParser();

parser.parse(content, function(error, graph) {
  console.log(graph);
});

$ cat graph.xml
<graphml xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://graphml.graphdrawing.org/xmlns">                               
    <graph id="G" edgedefault="directed">                                       
        <node id="1"></node>
    </graph>                            
</graphml>

$ node index.js
events.js:182
      throw er; // Unhandled 'error' event
      ^

TypeError: Cannot read property 'length' of undefined
    at GraphMLParser.buildEdges (/Users/syamaoka/tmp/graphmltest/node_modules/graphml-js/dist/graphml.js:129:56)
    at /Users/syamaoka/tmp/graphmltest/node_modules/graphml-js/dist/graphml.js:101:19
    at Parser.<anonymous> (/Users/syamaoka/tmp/graphmltest/node_modules/xml2js/lib/parser.js:303:18)
    at emitOne (events.js:115:13)
    at Parser.emit (events.js:210:7)
    at SAXParser.onclosetag (/Users/syamaoka/tmp/graphmltest/node_modules/xml2js/lib/parser.js:261:26)
    at emit (/Users/syamaoka/tmp/graphmltest/node_modules/sax/lib/sax.js:624:35)
    at emitNode (/Users/syamaoka/tmp/graphmltest/node_modules/sax/lib/sax.js:629:5)
    at closeTag (/Users/syamaoka/tmp/graphmltest/node_modules/sax/lib/sax.js:889:7)
    at SAXParser.write (/Users/syamaoka/tmp/graphmltest/node_modules/sax/lib/sax.js:1436:13)

The GraphML specification defines a graph as follows (excerpt from http://graphml.graphdrawing.org/xmlns/1.1/graphml-structure.xsd):

<xs:complexType name="graph.type" final="#all">
    <xs:annotation>
        <xs:documentation source="http://graphml.graphdrawing.org/" xml:lang="en">Complex type for the <graph> element.</xs:documentation>
    </xs:annotation>
    <xs:sequence>
        <xs:element ref="desc" minOccurs="0"/>
        <xs:choice>
            <xs:sequence>
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element ref="data"/>
                    <xs:element ref="node"/>
                    <xs:element ref="edge"/>
                    <xs:element ref="hyperedge"/>
                </xs:choice>
            </xs:sequence>
            <xs:element ref="locator"/>
        </xs:choice>
    </xs:sequence>

This XMLSchema defines the elements of graph.type as minOccurs=0, so it means that a graph which has no data, node, edge, and hyperedge is allowed.

shinnya commented 7 years ago

The location of code reported by the above error is like:

    GraphMLParser.prototype.buildEdges = function (data) {
        var edges = data.graphml.graph[0].edge;
        for (var _i = 0, edges_1 = edges; _i < edges_1.length; _i++) {
            var edge = edges_1[_i];

I believe I almost understood the root cause, so I will fix this issue.