Skip to content

Instantly share code, notes, and snippets.

@robvitaro
Created February 17, 2020 19:28
Show Gist options
  • Save robvitaro/0aad995eac3041e2f4ebd505d6efa256 to your computer and use it in GitHub Desktop.
Save robvitaro/0aad995eac3041e2f4ebd505d6efa256 to your computer and use it in GitHub Desktop.
Flatten an XML file to "full-xpath,value" csv file
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[@* or not(*)] ">
<xsl:if test="not(*)">
<xsl:apply-templates select="ancestor-or-self::*" mode="path"/>
<xsl:value-of select="concat(',',.)"/>
<xsl:text>&#xA;</xsl:text>
</xsl:if>
<xsl:apply-templates select="@*|*"/>
</xsl:template>
<xsl:template match="*" mode="path">
<xsl:value-of select="concat('/',name())"/>
<xsl:variable name="vnumPrecSiblings" select=
"count(preceding-sibling::*[name()=name(current())])"/>
<xsl:if test="$vnumPrecSiblings">
<xsl:value-of select="concat('[', $vnumPrecSiblings +1, ']')"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*">
<xsl:apply-templates select="../ancestor-or-self::*" mode="path"/>
<xsl:value-of select="concat('[@',name(),'],',.)"/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
</xsl:stylesheet>
require 'nokogiri'
document = Nokogiri::XML(File.read('input.xml'))
template = Nokogiri::XSLT(File.read('transformer.xslt'))
transformed_document = template.transform(document)
File.open('output.csv', 'w').write(transformed_document)
@robvitaro
Copy link
Author

robvitaro commented Feb 17, 2020

just have a file input.xml in the same directory these 2 files are in and run:
ruby xslt.rb

output.csv will spit out

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment