Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slimming an xml

I've a program producing one big xml every day and I want to save space, and there are some information that are not usefull after some time. I want to remove this information, for example my xml is now:

<owner name="thename">
   <datasets ndatasets="10" size="10000">
       <dataset size="100" creationdate="...">mydataset1</dataset>
       <dataset size="200" creationdate="...">mydataset2</dataset>
       ...
   </datasets>
</owner>
<owner name="thename2">
  ...
</owner>

I want to remove the information on the single datasets, so I want to tranform it in:

<owner name="thename">
   <datasets ndatasets="10" size="10000" />
</owner>
<owner name="thename2">
  ...
</owner>

What is the easiest way to do it? I'm using python, but also other easy and portable solutions are welcome

like image 452
Ruggero Turra Avatar asked Aug 06 '26 12:08

Ruggero Turra


2 Answers

An XSLT solution (Sean's solution is good, but it would stop working if elements or nodes other that dataset were made children of datasets):

<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="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>
 <xsl:template match="datasets/node()"/>
</xsl:stylesheet>

When this transformation is applied on the provided skeletal XML (wrapped into a single top element to make it a well-formed XML document):

<t>
    <owner name="thename">
        <datasets ndatasets="10" size="10000">
            <dataset size="100" creationdate="...">mydataset1</dataset>
            <dataset size="200" creationdate="...">mydataset2</dataset>
        </datasets>
    </owner>
    <owner name="thename2">
        <datasets ndatasets="10" size="10000">
            <dataset size="100" creationdate="...">mydataset1</dataset>
            <dataset size="200" creationdate="...">mydataset2</dataset>
        </datasets>
    </owner>
</t>

the wanted, correct result is produced:

<t>
   <owner name="thename">
      <datasets ndatasets="10" size="10000"/>
   </owner>
   <owner name="thename2">
      <datasets ndatasets="10" size="10000"/>
   </owner>
</t>

Explanation:

Proper use of the identity rule and overriding it with an empty-body template matching any child-node of datasets.

like image 116
Dimitre Novatchev Avatar answered Aug 08 '26 03:08

Dimitre Novatchev


Here is an XSLT 1.0 style-sheet:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="node()|@*">
 <xsl:copy>
  <xsl:apply-templates select="node()|@*"/>
 </xsl:copy>
</xsl:template>

<xsl:template match="dataset" />

</xsl:stylesheet>

Here is a couple of pointers to get you started on your XSLT journey:

  • http://www.w3schools.com/xsl/
  • https://stackoverflow.com/questions/3442827/good-books-on-xslt
like image 25
Sean B. Durkin Avatar answered Aug 08 '26 02:08

Sean B. Durkin