← Back to team overview

yade-users team mailing list archive

more XML editing


Here is more about manipulating YADE emitted xml
files. I thought it would be best to use a specialized
XML transformation tool and turned to XSLT, the xml
stylesheet transformation language. xsltproc was
installed already on my system. XSLT requires a bit of
adjustment but it lets you easily search and select
nodes in the xml tree. However, it has very limited
math and strings functions and is extremely verbose.
Below is an example xsl file which I used to remove
spheres above a certain threshold. A xslt processor
such as xsltproc loads the whole xml tree and outputs
an xml representation of the tree after applying the
transform. Therefore it always produces valid xml but
cannot preserve formatting.

Yade requires some more massaging of xsltproc output.
First the bodies need to be recounted and reindexed,
my awk script:

$0 ~ /_className_="Body"/ {i++;
$0 ~ /<body size=/ {bs = NR}
{ln[NR]= $0}
ln[bs] = "<body size=\""i"\">"
for (l = 1; l <= FNR; l++) print ln[l]

Then one may want to recolor spheres according to
their height, to get layered display:

$0 ~ /<physicalParameters/ {
 cuse3 = gensub(/}.*$/,"",1,gensub(/^.*se3=/,"",1))}
$0 ~ /<geometricalModel _className_=\"Sphere\"/ {
 split(cuse3,xzy," ")
 nz = xzy[2]/10
 dCol = "{"sin(nz)" "cos(nz)" "sin(nz*nz/100)"}"

This assumes that physicalParameter element is just
before the geometricalModel element and that both are
on one line.

Finally, Yade needs a space before an ending />
bracket. tidy does that and removes extra empty lines,
and checks for well-formedness:

tidy -xml -i inputscene.xml > outputscene.xml

The -i switch indents the output and is absolutely
required by yade for some reason.

A complete pipe therefore may looks like this:

xsltproc modifyscene.xsl scene78333.xml | awk -f
bodycount.awk | awk -f stratify.awk | tidy -xml -i >


Here the xsl to remove  spheres above a certain cutoff
height (0 by default):

<!-- use with xsltproc: xsltproc modifyscene.xsl
inputscene.xml -->
<xsl:transform version="1.0"
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:param name="cutoff" select='0' />
<!-- catches all bodies -->
<xsl:template match='bodies/body/body'>
<!-- extract height coordinate -->
 <xsl:variable name="height"
'),' ')" />
<!-- do nothing if above cutoff -->
  <xsl:when test="geometricalModel/@_className_ =
'Sphere' and $height > $cutoff"></xsl:when>
<!-- otherwise copy existing node -->
   <xsl:copy-of select="." />
<!-- get rid of interactions -->
 <xsl:element name="interaction">
  <xsl:attribute name="size">0</xsl:attribute>
<!-- copy everything else -->
<xsl:template match="@*|node()">
   <xsl:apply-templates select="@*|node()"/>

Yade-users mailing list

Follow ups