14.3. XSLT approach

14.3. XSLT approach

The document that describes XSL Transformations (XSLT) is available here:

http://www.w3.org/TR/xslt

14.3.1. Create a Pads-Pcb netlist file

The pads-pcb format is comprised of two sections.

  • The footprint list.
  • The Nets list: grouping pads references by nets.

Immediately below is a style-sheet which converts the Intermediate Netlist file to a pads-pcb netlist format:

  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <!--XSL style sheet to Eeschema Generic Netlist Format to PADS netlist format
  3. Copyright (C) 2010, SoftPLC Corporation.
  4. GPL v2.
  5. How to use:
  6. https://lists.launchpad.net/kicad-developers/msg05157.html
  7. -->
  8. <!DOCTYPE xsl:stylesheet [
  9. <!ENTITY nl "&#xd;&#xa;"> <!--new line CR, LF -->
  10. ]>
  11. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  12. <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
  13. <xsl:template match="/export">
  14. <xsl:text>*PADS-PCB*&nl;*PART*&nl;</xsl:text>
  15. <xsl:apply-templates select="components/comp"/>
  16. <xsl:text>&nl;*NET*&nl;</xsl:text>
  17. <xsl:apply-templates select="nets/net"/>
  18. <xsl:text>*END*&nl;</xsl:text>
  19. </xsl:template>
  20. <!-- for each component -->
  21. <xsl:template match="comp">
  22. <xsl:text> </xsl:text>
  23. <xsl:value-of select="@ref"/>
  24. <xsl:text> </xsl:text>
  25. <xsl:choose>
  26. <xsl:when test = "footprint != '' ">
  27. <xsl:apply-templates select="footprint"/>
  28. </xsl:when>
  29. <xsl:otherwise>
  30. <xsl:text>unknown</xsl:text>
  31. </xsl:otherwise>
  32. </xsl:choose>
  33. <xsl:text>&nl;</xsl:text>
  34. </xsl:template>
  35. <!-- for each net -->
  36. <xsl:template match="net">
  37. <!-- nets are output only if there is more than one pin in net -->
  38. <xsl:if test="count(node)>1">
  39. <xsl:text>*SIGNAL* </xsl:text>
  40. <xsl:choose>
  41. <xsl:when test = "@name != '' ">
  42. <xsl:value-of select="@name"/>
  43. </xsl:when>
  44. <xsl:otherwise>
  45. <xsl:text>N-</xsl:text>
  46. <xsl:value-of select="@code"/>
  47. </xsl:otherwise>
  48. </xsl:choose>
  49. <xsl:text>&nl;</xsl:text>
  50. <xsl:apply-templates select="node"/>
  51. </xsl:if>
  52. </xsl:template>
  53. <!-- for each node -->
  54. <xsl:template match="node">
  55. <xsl:text> </xsl:text>
  56. <xsl:value-of select="@ref"/>
  57. <xsl:text>.</xsl:text>
  58. <xsl:value-of select="@pin"/>
  59. <xsl:text>&nl;</xsl:text>
  60. </xsl:template>
  61. </xsl:stylesheet>

And here is the pads-pcb output file after running xsltproc:

  1. *PADS-PCB*
  2. *PART*
  3. P1 unknown
  4. U2 unknown
  5. U1 unknown
  6. C1 unknown
  7. R1 unknown
  8. *NET*
  9. *SIGNAL* GND
  10. U1.7
  11. C1.2
  12. U2.7
  13. P1.4
  14. *SIGNAL* VCC
  15. R1.1
  16. U1.14
  17. U2.4
  18. U2.1
  19. U2.14
  20. P1.1
  21. *SIGNAL* N-4
  22. U1.2
  23. U2.3
  24. *SIGNAL* /SIG_OUT
  25. P1.2
  26. U2.5
  27. U2.2
  28. *SIGNAL* /CLOCK_IN
  29. R1.2
  30. C1.1
  31. U1.1
  32. P1.3
  33. *END*

The command line to make this conversion is:

  1. kicad\\bin\\xsltproc.exe -o test.net kicad\\bin\\plugins\\netlist_form_pads-pcb.xsl test.tmp

14.3.2. Create a Cadstar netlist file

The Cadstar format is comprised of two sections.

  • The footprint list.
  • The Nets list: grouping pads references by nets.

Here is the style-sheet file to make this specific conversion:

  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <!--XSL style sheet to Eeschema Generic Netlist Format to CADSTAR netlist format
  3. Copyright (C) 2010, Jean-Pierre Charras.
  4. Copyright (C) 2010, SoftPLC Corporation.
  5. GPL v2.
  6. <!DOCTYPE xsl:stylesheet [
  7. <!ENTITY nl "&#xd;&#xa;"> <!--new line CR, LF -->
  8. ]>
  9. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  10. <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
  11. <!-- Netlist header -->
  12. <xsl:template match="/export">
  13. <xsl:text>.HEA&nl;</xsl:text>
  14. <xsl:apply-templates select="design/date"/> <!-- Generate line .TIM <time> -->
  15. <xsl:apply-templates select="design/tool"/> <!-- Generate line .APP <eeschema version> -->
  16. <xsl:apply-templates select="components/comp"/> <!-- Generate list of components -->
  17. <xsl:text>&nl;&nl;</xsl:text>
  18. <xsl:apply-templates select="nets/net"/> <!-- Generate list of nets and connections -->
  19. <xsl:text>&nl;.END&nl;</xsl:text>
  20. </xsl:template>
  21. <!-- Generate line .TIM 20/08/2010 10:45:33 -->
  22. <xsl:template match="tool">
  23. <xsl:text>.APP "</xsl:text>
  24. <xsl:apply-templates/>
  25. <xsl:text>"&nl;</xsl:text>
  26. </xsl:template>
  27. <!-- Generate line .APP "eeschema (2010-08-17 BZR 2450)-unstable" -->
  28. <xsl:template match="date">
  29. <xsl:text>.TIM </xsl:text>
  30. <xsl:apply-templates/>
  31. <xsl:text>&nl;</xsl:text>
  32. </xsl:template>
  33. <!-- for each component -->
  34. <xsl:template match="comp">
  35. <xsl:text>.ADD_COM </xsl:text>
  36. <xsl:value-of select="@ref"/>
  37. <xsl:text> </xsl:text>
  38. <xsl:choose>
  39. <xsl:when test = "value != '' ">
  40. <xsl:text>"</xsl:text> <xsl:apply-templates select="value"/> <xsl:text>"</xsl:text>
  41. </xsl:when>
  42. <xsl:otherwise>
  43. <xsl:text>""</xsl:text>
  44. </xsl:otherwise>
  45. </xsl:choose>
  46. <xsl:text>&nl;</xsl:text>
  47. </xsl:template>
  48. <!-- for each net -->
  49. <xsl:template match="net">
  50. <!-- nets are output only if there is more than one pin in net -->
  51. <xsl:if test="count(node)>1">
  52. <xsl:variable name="netname">
  53. <xsl:text>"</xsl:text>
  54. <xsl:choose>
  55. <xsl:when test = "@name != '' ">
  56. <xsl:value-of select="@name"/>
  57. </xsl:when>
  58. <xsl:otherwise>
  59. <xsl:text>N-</xsl:text>
  60. <xsl:value-of select="@code"/>
  61. </xsl:otherwise>
  62. </xsl:choose>
  63. <xsl:text>"&nl;</xsl:text>
  64. </xsl:variable>
  65. <xsl:apply-templates select="node" mode="first"/>
  66. <xsl:value-of select="$netname"/>
  67. <xsl:apply-templates select="node" mode="others"/>
  68. </xsl:if>
  69. </xsl:template>
  70. <!-- for each node -->
  71. <xsl:template match="node" mode="first">
  72. <xsl:if test="position()=1">
  73. <xsl:text>.ADD_TER </xsl:text>
  74. <xsl:value-of select="@ref"/>
  75. <xsl:text>.</xsl:text>
  76. <xsl:value-of select="@pin"/>
  77. <xsl:text> </xsl:text>
  78. </xsl:if>
  79. </xsl:template>
  80. <xsl:template match="node" mode="others">
  81. <xsl:choose>
  82. <xsl:when test='position()=1'>
  83. </xsl:when>
  84. <xsl:when test='position()=2'>
  85. <xsl:text>.TER </xsl:text>
  86. </xsl:when>
  87. <xsl:otherwise>
  88. <xsl:text> </xsl:text>
  89. </xsl:otherwise>
  90. </xsl:choose>
  91. <xsl:if test="position()>1">
  92. <xsl:value-of select="@ref"/>
  93. <xsl:text>.</xsl:text>
  94. <xsl:value-of select="@pin"/>
  95. <xsl:text>&nl;</xsl:text>
  96. </xsl:if>
  97. </xsl:template>
  98. </xsl:stylesheet>

Here is the Cadstar output file.

  1. .HEA
  2. .TIM 21/08/2010 08:12:08
  3. .APP "eeschema (2010-08-09 BZR 2439)-unstable"
  4. .ADD_COM P1 "CONN_4"
  5. .ADD_COM U2 "74LS74"
  6. .ADD_COM U1 "74LS04"
  7. .ADD_COM C1 "CP"
  8. .ADD_COM R1 "R"
  9. .ADD_TER U1.7 "GND"
  10. .TER C1.2
  11. U2.7
  12. P1.4
  13. .ADD_TER R1.1 "VCC"
  14. .TER U1.14
  15. U2.4
  16. U2.1
  17. U2.14
  18. P1.1
  19. .ADD_TER U1.2 "N-4"
  20. .TER U2.3
  21. .ADD_TER P1.2 "/SIG_OUT"
  22. .TER U2.5
  23. U2.2
  24. .ADD_TER R1.2 "/CLOCK_IN"
  25. .TER C1.1
  26. U1.1
  27. P1.3
  28. .END

14.3.3. Create a OrcadPCB2 netlist file

This format has only one section which is the footprint list. Each footprint includes its list of pads with reference to a net.

Here is the style-sheet for this specific conversion:

  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <!--XSL style sheet to Eeschema Generic Netlist Format to CADSTAR netlist format
  3. Copyright (C) 2010, SoftPLC Corporation.
  4. GPL v2.
  5. How to use:
  6. https://lists.launchpad.net/kicad-developers/msg05157.html
  7. -->
  8. <!DOCTYPE xsl:stylesheet [
  9. <!ENTITY nl "&#xd;&#xa;"> <!--new line CR, LF -->
  10. ]>
  11. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  12. <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
  13. <!--
  14. Netlist header
  15. Creates the entire netlist
  16. (can be seen as equivalent to main function in C
  17. -->
  18. <xsl:template match="/export">
  19. <xsl:text>( { Eeschema Netlist Version 1.1 </xsl:text>
  20. <!-- Generate line .TIM <time> -->
  21. <xsl:apply-templates select="design/date"/>
  22. <!-- Generate line eeschema version ... -->
  23. <xsl:apply-templates select="design/tool"/>
  24. <xsl:text>}&nl;</xsl:text>
  25. <!-- Generate the list of components -->
  26. <xsl:apply-templates select="components/comp"/> <!-- Generate list of components -->
  27. <!-- end of file -->
  28. <xsl:text>)&nl;*&nl;</xsl:text>
  29. </xsl:template>
  30. <!--
  31. Generate id in header like "eeschema (2010-08-17 BZR 2450)-unstable"
  32. -->
  33. <xsl:template match="tool">
  34. <xsl:apply-templates/>
  35. </xsl:template>
  36. <!--
  37. Generate date in header like "20/08/2010 10:45:33"
  38. -->
  39. <xsl:template match="date">
  40. <xsl:apply-templates/>
  41. <xsl:text>&nl;</xsl:text>
  42. </xsl:template>
  43. <!--
  44. This template read each component
  45. (path = /export/components/comp)
  46. creates lines:
  47. ( 3EBF7DBD $noname U1 74LS125
  48. ... pin list ...
  49. )
  50. and calls "create_pin_list" template to build the pin list
  51. -->
  52. <xsl:template match="comp">
  53. <xsl:text> ( </xsl:text>
  54. <xsl:choose>
  55. <xsl:when test = "tstamp != '' ">
  56. <xsl:apply-templates select="tstamp"/>
  57. </xsl:when>
  58. <xsl:otherwise>
  59. <xsl:text>00000000</xsl:text>
  60. </xsl:otherwise>
  61. </xsl:choose>
  62. <xsl:text> </xsl:text>
  63. <xsl:choose>
  64. <xsl:when test = "footprint != '' ">
  65. <xsl:apply-templates select="footprint"/>
  66. </xsl:when>
  67. <xsl:otherwise>
  68. <xsl:text>$noname</xsl:text>
  69. </xsl:otherwise>
  70. </xsl:choose>
  71. <xsl:text> </xsl:text>
  72. <xsl:value-of select="@ref"/>
  73. <xsl:text> </xsl:text>
  74. <xsl:choose>
  75. <xsl:when test = "value != '' ">
  76. <xsl:apply-templates select="value"/>
  77. </xsl:when>
  78. <xsl:otherwise>
  79. <xsl:text>"~"</xsl:text>
  80. </xsl:otherwise>
  81. </xsl:choose>
  82. <xsl:text>&nl;</xsl:text>
  83. <xsl:call-template name="Search_pin_list" >
  84. <xsl:with-param name="cmplib_id" select="libsource/@part"/>
  85. <xsl:with-param name="cmp_ref" select="@ref"/>
  86. </xsl:call-template>
  87. <xsl:text> )&nl;</xsl:text>
  88. </xsl:template>
  89. <!--
  90. This template search for a given lib component description in list
  91. lib component descriptions are in /export/libparts,
  92. and each description start at ./libpart
  93. We search here for the list of pins of the given component
  94. This template has 2 parameters:
  95. "cmplib_id" (reference in libparts)
  96. "cmp_ref" (schematic reference of the given component)
  97. -->
  98. <xsl:template name="Search_pin_list" >
  99. <xsl:param name="cmplib_id" select="0" />
  100. <xsl:param name="cmp_ref" select="0" />
  101. <xsl:for-each select="/export/libparts/libpart">
  102. <xsl:if test = "@part = $cmplib_id ">
  103. <xsl:apply-templates name="build_pin_list" select="pins/pin">
  104. <xsl:with-param name="cmp_ref" select="$cmp_ref"/>
  105. </xsl:apply-templates>
  106. </xsl:if>
  107. </xsl:for-each>
  108. </xsl:template>
  109. <!--
  110. This template writes the pin list of a component
  111. from the pin list of the library description
  112. The pin list from library description is something like
  113. <pins>
  114. <pin num="1" type="passive"/>
  115. <pin num="2" type="passive"/>
  116. </pins>
  117. Output pin list is ( <pin num> <net name> )
  118. something like
  119. ( 1 VCC )
  120. ( 2 GND )
  121. -->
  122. <xsl:template name="build_pin_list" match="pin">
  123. <xsl:param name="cmp_ref" select="0" />
  124. <!-- write pin numner and separator -->
  125. <xsl:text> ( </xsl:text>
  126. <xsl:value-of select="@num"/>
  127. <xsl:text> </xsl:text>
  128. <!-- search net name in nets section and write it: -->
  129. <xsl:variable name="pinNum" select="@num" />
  130. <xsl:for-each select="/export/nets/net">
  131. <!-- net name is output only if there is more than one pin in net
  132. else use "?" as net name, so count items in this net
  133. -->
  134. <xsl:variable name="pinCnt" select="count(node)" />
  135. <xsl:apply-templates name="Search_pin_netname" select="node">
  136. <xsl:with-param name="cmp_ref" select="$cmp_ref"/>
  137. <xsl:with-param name="pin_cnt_in_net" select="$pinCnt"/>
  138. <xsl:with-param name="pin_num"> <xsl:value-of select="$pinNum"/>
  139. </xsl:with-param>
  140. </xsl:apply-templates>
  141. </xsl:for-each>
  142. <!-- close line -->
  143. <xsl:text> )&nl;</xsl:text>
  144. </xsl:template>
  145. <!--
  146. This template writes the pin netname of a given pin of a given component
  147. from the nets list
  148. The nets list description is something like
  149. <nets>
  150. <net code="1" name="GND">
  151. <node ref="J1" pin="20"/>
  152. <node ref="C2" pin="2"/>
  153. </net>
  154. <net code="2" name="">
  155. <node ref="U2" pin="11"/>
  156. </net>
  157. </nets>
  158. This template has 2 parameters:
  159. "cmp_ref" (schematic reference of the given component)
  160. "pin_num" (pin number)
  161. -->
  162. <xsl:template name="Search_pin_netname" match="node">
  163. <xsl:param name="cmp_ref" select="0" />
  164. <xsl:param name="pin_num" select="0" />
  165. <xsl:param name="pin_cnt_in_net" select="0" />
  166. <xsl:if test = "@ref = $cmp_ref ">
  167. <xsl:if test = "@pin = $pin_num">
  168. <!-- net name is output only if there is more than one pin in net
  169. else use "?" as net name
  170. -->
  171. <xsl:if test = "$pin_cnt_in_net>1">
  172. <xsl:choose>
  173. <!-- if a net has a name, use it,
  174. else build a name from its net code
  175. -->
  176. <xsl:when test = "../@name != '' ">
  177. <xsl:value-of select="../@name"/>
  178. </xsl:when>
  179. <xsl:otherwise>
  180. <xsl:text>$N-0</xsl:text><xsl:value-of select="../@code"/>
  181. </xsl:otherwise>
  182. </xsl:choose>
  183. </xsl:if>
  184. <xsl:if test = "$pin_cnt_in_net &lt;2">
  185. <xsl:text>?</xsl:text>
  186. </xsl:if>
  187. </xsl:if>
  188. </xsl:if>
  189. </xsl:template>
  190. </xsl:stylesheet>

Here is the OrcadPCB2 output file.

  1. ( { Eeschema Netlist Version 1.1 29/08/2010 21:07:51
  2. eeschema (2010-08-28 BZR 2458)-unstable}
  3. ( 4C6E2141 $noname P1 CONN_4
  4. ( 1 VCC )
  5. ( 2 /SIG_OUT )
  6. ( 3 /CLOCK_IN )
  7. ( 4 GND )
  8. )
  9. ( 4C6E20BA $noname U2 74LS74
  10. ( 1 VCC )
  11. ( 2 /SIG_OUT )
  12. ( 3 N-04 )
  13. ( 4 VCC )
  14. ( 5 /SIG_OUT )
  15. ( 6 ? )
  16. ( 7 GND )
  17. ( 14 VCC )
  18. )
  19. ( 4C6E20A6 $noname U1 74LS04
  20. ( 1 /CLOCK_IN )
  21. ( 2 N-04 )
  22. ( 7 GND )
  23. ( 14 VCC )
  24. )
  25. ( 4C6E2094 $noname C1 CP
  26. ( 1 /CLOCK_IN )
  27. ( 2 GND )
  28. )
  29. ( 4C6E208A $noname R1 R
  30. ( 1 VCC )
  31. ( 2 /CLOCK_IN )
  32. )
  33. )
  34. *

14.3.4. Eeschema plugins interface

Intermediate Netlist converters can be automatically launched within Eeschema.

Init the Dialog window

One can add a new netlist plug-in user interface tab by clicking on the Add Plugin button.

eeschema_plugin_add_plugin_png

Here is what the configuration data for the PadsPcb tab looks like:

eeschema_plugin_padspcb_png

Plugin Configuration Parameters

The Eeschema plug-in configuration dialog requires the following information:

  • The title: for instance, the name of the netlist format.
  • The command line to launch the converter.

Once you click on the netlist button the following will happen:

  1. Eeschema creates an intermediate netlist file *.xml, for instance test.xml.
  2. Eeschema runs the plug-in by reading test.xml and creates test.net.

Generate netlist files with the command line

Assuming we are using the program xsltproc.exe to apply the sheet style to the intermediate file, xsltproc.exe is executed with the following command:

xsltproc.exe -o <output filename> < style-sheet filename> <input XML file to convert>

In KiCad under Windows the command line is the following:

f:/kicad/bin/xsltproc.exe -o “%O” f:/kicad/bin/plugins/netlist_form_pads-pcb.xsl “%I”

Under Linux the command becomes as follows:

xsltproc -o “%O” /usr/local/kicad/bin/plugins/netlist_form_pads-pcb.xsl “%I”

Where netlist_form_pads-pcb.xsl is the style-sheet that you are applying. Do not forget the double quotes around the file names, this allows them to have spaces after the substitution by Eeschema.

The command line format accepts parameters for filenames:

The supported formatting parameters are.

  • %B ⇒ base filename and path of selected output file, minus path and extension.
  • %I ⇒ complete filename and path of the temporary input file (the intermediate net file).
  • %O ⇒ complete filename and path of the user chosen output file.

%I will be replaced by the actual intermediate file name

%O will be replaced by the actual output file name.

Command line format: example for xsltproc

The command line format for xsltproc is the following:

<path of xsltproc> xsltproc <xsltproc parameters>

under Windows:

f:/kicad/bin/xsltproc.exe -o “%O” f:/kicad/bin/plugins/netlist_form_pads-pcb.xsl “%I”

under Linux:

xsltproc -o “%O” /usr/local/kicad/bin/plugins/netlist_form_pads-pcb.xsl “%I”

The above examples assume xsltproc is installed on your PC under Windows and all files located in kicad/bin.

14.3.5. Bill of Materials Generation

Because the intermediate netlist file contains all information about used components, a BOM can be extracted from it. Here is the plug-in setup window (on Linux) to create a customized Bill Of Materials (BOM) file:

bom-netlist-tab_png

The path to the style sheet bom2csv.xsl is system dependent. The currently best XSLT style-sheet for BOM generation at this time is called bom2csv.xsl. You are free to modify it according to your needs, and if you develop something generally useful, ask that it become part of the KiCad project.