Where to Discuss?

Local Group

Preface

Query layer using inkscape extension.

Here we are going to learn to access XML tree.


The XML Properties

Example SVG

The Test Bed

We need any working SVG file with layer. You can choose any of these two test bed:

Certificate Test Bed 04

Layers

Consider open one of those, and examine all layers.

All Layers

Layer in XML

Group Mode

Again, examine all layers in XML representation.

All Layers in XML Editor

You can spot the layer properties in XML editor. It has ‘inkscape:groupmodeaslayer`.

This is the basic of our query.

Text Editor

You can also open the file using any text editor, and do some find tools.

All Layers in Text Editor


Query Layer Extension

Artefacts

We need two files.

  • query_layer.inx
  • query_layer.py

Query Layer XML

<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension
  xmlns="http://www.inkscape.org/namespace/inkscape/extension">
  <name>Query Layer</name>
  <id>epsi.query_layer</id>
  <effect>
    <object-type>all</object-type>
    <effects-menu>
       <submenu name="Epsi"/>
    </effects-menu>
  </effect>
  <script>
    <command location="inx"
             interpreter="python">query_layer.py</command>
  </script>
</inkscape-extension>

Query Layer Python

The structure of the extension is shown as below.

#!/usr/bin/env python
import inkex

class QueryLayer(inkex.EffectExtension):
  def effect(self):
    self.recurse(1, self.svg)

  ...

if __name__ == "__main__":
    QueryLayer().run()

Notice the self.svg as the root node.

Recurse Method

Recurse and the supporting method is as below:

class QueryLayer(inkex.EffectExtension):
  ...

  def recurse(self, level, nodes):
    for node in sorted(nodes, key =  self._sort):
      if isinstance(node, inkex.ShapeElement):
        if node.get('inkscape:groupmode') == 'layer':
          self.print_layer_name(level, node)
          self.recurse(level+1, node)

  def print_layer_name(self, level, node):
    label_name = node.get('inkscape:label')
    inkex.errormsg('-'*level + ' ' +label_name)

Notice the get method from node to get any property, such as inkscape:groupmode.

Sorting

Instead of filter, we can also add sort feature as below method:

  def _sort(self, node):
    if node.get('inkscape:groupmode') == 'layer':
      return node.get('inkscape:label')
    else:
      return  ""

_

What Does It Do?

This will throw the result using inkex.errormsg.

Query Layer Result - Error Message

Caveat

The code above rely on this code

if node.get('inkscape:groupmode') == 'layer':

For complex layer, this approach does not always work. I prefer to use inkscape:label instead.

if node.get('inkscape:label') is not None:

Final Code

Now our final code will be:

#!/usr/bin/env python
import inkex

class QueryLayer(inkex.EffectExtension):
  def effect(self):
    self.recurse(1, self.svg)

  def recurse(self, level, nodes):
    for node in sorted(nodes, key =  self._sort):
      if isinstance(node, inkex.ShapeElement):
        if node.get('inkscape:label') is not None:
          self.print_layer_name(level, node)
          self.recurse(level+1, node)

  def print_layer_name(self, level, node):
    label_name = node.get('inkscape:label')
    inkex.errormsg('-'*level + ' ' +label_name)

  def _sort(self, node):
    if node.get('inkscape:label') is not None:
      return node.get('inkscape:label')
    else:
      return  ""

if __name__ == "__main__":
    QueryLayer().run()

What is Next ?

Consider continue reading [ Inkscape Extension - Part Three ].

Thank you for reading.