Guide on retrieving information from various svg documents and saving it within a javascript array

I have a collection of svg files that are structured like this:

<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 684.214 684.214" style="enable-background:new 0 0 684.214 684.214;" xml:space="preserve">
<g>
    <g>
        <g>
            <path style="fill:#010002;" d="M285.22,103.603h49.476v222.613h-89.065L285.22,103.603z M349.567,103.603v222.613h89.065
                l-39.579-222.613H349.567z M557.652,215.549c0,119.059-215.549,468.665-215.549,468.665
                s-215.54-349.606-215.54-468.665
                C126.563,96.519,223.063,0,342.112,0S557.671,96.519,557.652,215.549z M508.908,215.549c0-91.957-74.83-166.777-166.796-166.777
                s-166.786,74.82-166.786,166.777s74.82,166.796,166.786,166.796S508.908,307.506,508.908,215.549z"/>
        </g>
    </g>
</g>
<g>
</g>
<g>
</g>
...

My goal is to extract the 'path d value' and 'viewBox values' for each svg file and store them in an array structured like this:

 data = [
        ['0 0 499.392 499.392', 'M409.81,160.113C409.79,71.684,338.136,0,249.725,0C161.276,0,89.583,71.684,89.583,160.113 ...'],
        ['0 0 498.923 498.923', 'M249.462,0C151.018,0,70.951,80.106,70.951,178.511c0,92.436,133.617,192.453,172.248,315.948 ...'],
        ...
];

Anyone have any ideas how to accomplish this task?

Edit:
I would like to loop through the array and generate svgs for use in a web browser:

for (var i=0; i<data.length; i++) {
            html += '<div class="tour-tag-icon" data-path="'+ data[i][1] +'" data-viewbox="'+ data[i][0] +'">';
            html += '   <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="'+ data[i][0] +'" xml:space="preserve" width="40px" height="40px">';
            html += '       <path d="'+ data[i][1] +'"></path>';
            html += '   </svg>';
            html += '</div>';
}

-- Updated --

Completed code - Thanks to Jinyoung Kim

This code searches through the 'svg' directory, retrieves all svg files automatically.

Looks through 'svg' directory and automatically finds all svg files

function getDatum($) {
  return [$('svg').attr('viewBox'), $('path').attr('d')];
}

function generateJson() {
  fs.writeFile('./output.json', JSON.stringify(results), 'utf8', function () {
    console.log('completed!');
    process.exit(); 
  });
}

Answer №1

If you are working with node.js, the cheerio module is highly recommended for your task. I have provided a rough code snippet below which should help you achieve your desired outcome.

const cheerio = require('cheerio');
const fs = require('fs');

const paths = [
  'image1.svg',
  'image2.svg'
  // Add all your SVG file paths here
];

const results = [];
let count = 0;

paths.forEach((path) => {
  fs.readFile(path, 'utf8', (err, data) => {
    if (err) { return console.error(err); }

    const $ = cheerio.load(data, { xmlMode: true });
    const imageData = getSvgData($);
    results.push(imageData);

    count++;
    if (paths.length === count) { createJsonFile(); }
  });
});

function getSvgData($) {
  return [$('svg').attr('viewBox'), $('path').attr('d')];
}

function createJsonFile() {
  fs.writeFile('./output.json', JSON.stringify(results), 'utf8', () => {
    console.log('Process completed successfully!');
    process.exit();
  });
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to transform a regular CommonJS declaration into an ECMAScript import when it is making multiple requires in a single line?

As a beginner in JavaScript, I am interested in converting this line into an import statement: var sass = require('gulp-sass')(require('sass')); I have successfully converted the other requires into imports but I'm struggling wit ...

Deactivating the submit button after a single click without compromising the form's functionality

In the past, I have posed this question without receiving a satisfactory solution. On my quiz website, I have four radio buttons for answer options. Upon clicking the submit button, a PHP script determines if the answer is accurate. My goal is to disable t ...

Angular element for dynamic background image based on conditions

I am searching for a directive that can automatically set the background image to a specific image if it exists, or default to another image. The url is generated using the form /images/cards/card{{$index}}.jpg within an ng-repeat, however, not all images ...

Experiencing perplexity due to receiving this error message: "Unable to access property 'checked' of an undefined or null reference."

When using .checked in a Function, it stops working and generates the following Error. I am currently utilizing Visual Studio 2015. Please assist. function GenderValidation(sender , e) { var male = document.getElementById('RadioButton_mal ...

Retrieving JSON information and refreshing the display

Currently, I am utilizing OnsenUI in conjunction with AngularJS to create a searching application. On page1, the user inputs the data they wish to search for. Upon clicking the search button, page1 is added to the stack and a background GET request is trig ...

How can I create the effect of text changing color automatically after a specified time period has elapsed

I am currently dealing with a timer that is functioning properly, but I have a specific CSS inquiry. Essentially, what I would like to achieve is when the timer hits 30 seconds, I want the numbers to change to red color. $(function () { var $startTimer = ...

Is there a way to activate a click event when I click on a button that is located outside of the dialog element?

In my Vue 3 app, I am using the native HTML dialog element as a modal. I have managed to position a button outside of the modal with absolute positioning. However, I am facing an issue where I cannot trigger a click event (displayNextModal) when clicking ...

The watch function remains inactive until it is triggered by an event

My current issue involves using $watch for pagination on my page. Unfortunately, the data is not appearing until I click on one of the buttons. Below is the relevant code snippet: .controller('AppCtrl', function ($scope, $modal, Faq) { $sco ...

The textarea field activates a select event listener whenever a button or link is clicked within the DOM

My DOM structure is pretty straightforward, consisting of a textarea, some buttons, and links. I've attached a select eventlistener to the textarea to monitor text selection by the user. const summary = document.getElementById("summary"); summary?. ...

Creating a component that responds to changes in the state data

In my Vue application, I have the following layout: App.vue <template> <div id="app"> <Progress /> <router-view /> <Footer /> </div> </template> <script> import Footer from "@/components/Fo ...

Discovering components within a 3 by 3 matrix

I am a beginner in the world of programming, and I have successfully created a tic-tac-toe game. However, I am now looking to enhance the computer's "intelligence" in the game. The traditional 3 by 3 tic-tac-toe board (resembling "#") is represented ...

From time to time, I may post files of substantial size

When moving to the next step in the form, I have implemented checks to prevent photos over 10mb and disallow .heic files from being uploaded. Most of the time it works as expected, but occasionally files slip through. If anyone has suggestions for a more ...

What is the best way to identify the highest three test scores along with the corresponding names in my array?

I have completed the initial two steps of my assignment according to my teacher's instructions, which were to: calculate and display the average score for each exam calculate and display the average score for each student, along with the highest scor ...

Create reactivity in output by utilizing global functions in Vue

I've recently dived into Vue, along with vue-cli and Single File Components. I'm facing a challenge where I need to have a global function that provides formatted text to components throughout my application. This text should be based on the curr ...

How do I assign a value to a multi-dimensional array in statically compiled Groovy?

I am working with a Groovy multi-dimensional array structure: boolean[][] arr = new boolean[10][10] In addition, I have defined a boolean variable: boolean value = true My next step is to assign the boolean value to an element in the array: arr[1][1] ...

Flexbox causing issues with relative positioning at the bottom of the screen in various browsers

My flex component looks like this: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" ... width="100%" height="100%" creationComplete="init()"> ....... <components:Naviga ...

The initial JavaScript load shared by all users is quite large in the next.js framework

Currently working on a project using the Next.js framework and facing an issue where the First Load JS shared by all pages is quite heavy. I am looking for advice on possible strategies to reduce the weight of the JS file, and also wondering if there ...

Encountered a "Transformer is not a constructor" error when trying to upgrade the React Native SDK version from 0.61.5 to 0.64

https://i.sstatic.net/LYdxj.pngRecently, I upgraded my react native version to the latest one and encountered an error stating "Transformer is not a constructor". The metro-react-native-babel-preset version I am currently using is 0.64.0. Can someone ple ...

Achieve horizontal bar movement by utilizing google.visualization.DataTable in a left-to-right motion

I am exploring the possibility of reversing the direction of a chart(bar) using google.visualization.DataTable. In the current setup, the bar progresses from left to right, but I wish for it to move from right to left instead. Below is what I have attempte ...

Sending data back and forth across 2 tabs within one page

I noticed a strange behavior when using multiple tabs on the same page in different modes. When I clicked a button that was supposed to fill in some inputs, the data filled in the last tab opened instead of the one I actually clicked on. The angular input: ...