0

I am trying to read a .graphml that yEd (yEd) generates. I am able to read simple and manually-generated .graphml files but the yEd files contains several properties to be defined. Does any one has a running example that show how to deal with such yEd files?

GDG
  • 397
  • 5
  • 14
  • Essentially the main issue is with the yFiles extensions that yEd introduces w.r.t. vanilla GraphML format. I do not know how to take care of the yfiles.type in ``. – GDG Jul 28 '13 at 21:21

2 Answers2

3

The yED file must be filtered to remove all the yEd stuff that boost::read_graphml does not recognize. If all you want is the vertices and edges, this is simple enough. However, if you do want some of the attributes, then it becomes more complex, and will depend on what you need.

Here is some code that filters out all the yED stuff, except the text of the node labels, which is converted to the simplest possible node label attribute that boost::read_graphml can parse and store in a bundled property.

/**

  Check for a yEd file

  @param[in] n  the filename
  @return true if the file weas written by yED

  The input file is copied to a new file graphex_processed.graphml
  If the intput file was NOT produced by yEd, then the copy is perfect
  If input was produced by yEd then the copy is filtered so that it can be
  read by boost::read_graphml
  Most of the yEd stuff is discarded, except for the node labels
  the text of which are copied to a simple node attribute "label"

*/

bool cGraph::IsGraphMLbyYED(const std::wstring& n)
{
    bool yEd = false;

    // open the input file
    std::ifstream fin;
    fin.open(n.c_str(), std::ifstream::in);
    if( ! fin.is_open() ) {
        return false;
    }
    // open the output file
    std::ofstream fout;
    fout.open("graphex_processed.graphml", std::ifstream::out );
    if( ! fout.is_open() ) {
        return false;
    }


    // loop over input file lines
    fin.clear();
    char buf[1000];
    while( fin.good() ) {
        fin.getline( buf,999 );
        std::string l( buf ); 

        // check for file produced by yEd
        if( l.find("<!--Created by yFiles") != -1 ) {
            yEd = true;
            // convert NodeLabel text to simple label attribute
            fout << "<key id=\"key0\" for=\"node\" attr.name=\"label\" attr.type=\"string\" />\n";
        }

        // check for file already identified as yEd
        if( yEd ) {

            // filter out yED attributes
            if( l.find("<key") != -1 ) {
                continue;
            }
            // convert NodeLabel text
            if( l.find("<y:NodeLabel") != -1 ) {
                int p = l.find(">")+1;
                int q = l.find("<",p);
                std::string label = l.substr(p,q-p);
                fout << "<data key=\"key0\">" << label << "</data>\n";
                continue;
            }

            // filter out outher yEd stuff
            if( l.find("<y:") != -1 ) {
                continue;
            }
            if( l.find("</y:") != -1 ) {
                continue;
            }
            if( l.find("<data") != -1 ) {
                continue;
            }
            if( l.find("</data") != -1 ) {
                continue;
            }
        }
        // copy input line to output
        fout << buf << std::endl;
    }

    // close files
    fin.close();
    fout.close();

    // return true if yED file
    return yEd;

}

Here is some code to read the filtered file

void cGraph::ReadGraphML(const std::wstring& n)
{
    // check if file was produced by yEd
    IsGraphMLbyYED( n ); 

    boost::dynamic_properties dp;
    dp.property("label", boost::get(&cVertex::myName, myGraph));


    myGraph.clear();
    std::ifstream fin;
    fin.open("graphex_processed.graphml", std::ifstream::in);
    if( ! fin.is_open() ) {
        return;
    }
    boost::read_graphml( fin, myGraph, dp );
}

If you want to see an example of this running in an application, take a look at Graphex, a GUI for the BGL, which can read yEd files using this code.

ravenspoint
  • 19,093
  • 6
  • 57
  • 103
-1

Try this workaround:

https://stackoverflow.com/a/55807107/4761831

I just inherited a class and removed some codes that cause the exception.