Search code examples
javascriptjquerytampermonkey

How to parse svg polyline data from url using JSON.parse() in JavaScript?


I simply want to parse some data of this svg from this url:http://colorillo.com/bxys.inline.svg When I view the source of the page. I would like to parse the points and stroke data and send it to google's console using console.log()

My code is shown below, this is what I tried to do but had no luck of getting it to print into the console.

    var url = new url("http://colorillo.com/bxys.inline.svg");

    url = function(e) {
    var obj = JSON.parse(e.data);
    var points = JSON.stringify(obj.points)
    var stroke = JSON.stringify(obj.stroke)
    }

    console.log(points)
    console.log(stroke)


Solution

  • There are various problems with your code, like defining url twice. You probably want to use the fetch API to get it. You'll have to run your code on colorillo.com or rehost the file on your own server, because they haven't set up CORS to allow you to access the file from another website.

    SVG is a dialect of XML, not JSON. You need to use a DOMParser:

    // Create request to fetch the SVG file.
    xhr=new XMLHttpRequest();
    // Tell the request where the file is.
    xhr.open("GET", "http://colorillo.com/bxys.inline.svg");
    // Add event handler to process the file once it's been fetched.
    xhr.addEventListener("load", function() {
      // Once the text is available, create an XML parser
      // and parse the text as an SVG image.
      const xmlDoc = new DOMParser().parseFromString(
        this.responseText.trim(), 
        "image/svg+xml"
      );
      // xmlDoc.getElements() returns something Array-like, but not an Array.
      // This turns it into an Array.
      const polylines = Array.from(xmlDoc.getElementsByTagName('polyline'));
      console.log(polylines.map(
        pl => [
          // Parses each 'points' attribute into an array of pairs of numbers
          pl.getAttribute('points').split(' ').map(
            pair => pair.split(',').map(x=>+x)
          ),
          // Various stroke information
    
          // Convert rgb(R,G,B) to #RRGGBB
          // Leading hash, then pull out the digits with a regex
          '#' + pl.style.stroke.match(/rgb\((\d*), (\d*), (\d*)\)/)
            // Throw away everything but the digits
            .slice(1,4)
            // Convert to a number, render in hex, uppercase, pad with 0s
            .map(x=>(+x).toString(16).toUpperCase().padStart(2,'0'))
            // Concatenate the hex digits
            .join(''),
          +pl.style.strokeWidth,
          pl.style.strokeLinejoin,
          pl.style.strokeLinecap
        ]
      ));
    });
    xhr.send();