This one I'm struggling with for a few day's now. I can solve little parts of the puzzle but when trying to merge it into one xslt stylesheet I'm completely lost.
The source xml looks like this (simplified)
<tr>
<pic>
<hs>
<spot>
<posit>
<pan>28</pan>
<tilt>44</tilt>
</posit>
<id>_flare</id>
</spot>
<spot>
<posit>
<pan>6</pan>
<tilt>7</tilt>
</posit>
</spot>
<spot>
<posit>
<pan>4</pan>
<tilt>8</tilt>
</posit>
<id>Point01</id>
</spot>
</hs>
<snd>
<level>1</level>
<sound>
<loop>1</loop>
</sound>
</snd>
</pic>
</tr>
The expected output should look like this:
<tr>
<pic>
<hs>
<spot>
<posit>
<pan>6</pan>
<tilt>7</tilt>
</posit>
</spot>
<spot>
<posit>
<pan>4</pan>
<tilt>8</tilt>
</posit>
<id>Point01</id>
</spot>
</hs>
<snd>
<level>1</level>
<sound>
<loop>1</loop>
</sound>
<lf>
<pos>
<pan>28</pan>
<tilt>44</tilt>
</pos>
<col>#ffffff</col>
</lf>
</snd>
</pic>
</tr>
I think it needs some explanation. Only the "spot" with an "id" that matches "_flare" in "hs" should be moved and added to the "snd" element. It also has to be reformatted from:
<spot>
<posit>
<pan>28</pan>
<tilt>44</tilt>
</posit>
<id>_flare</id>
</spot>
to
<lf>
<pos>
<pan>28</pan>
<tilt>44</tilt>
</pos>
<col>#ffffff</col>
</lf>
I appreciate a hint in the right direction to get me going again !
Regards,
AHG
How about:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="spot[id='_flare']"/>
<xsl:template match="snd">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select="../hs/spot[id='_flare']" mode="add"/>
</xsl:copy>
</xsl:template>
<xsl:template match="spot" mode="add">
<lf>
<pos>
<xsl:copy-of select="posit/pan | posit/tilt"/>
</pos>
<col>#ffffff</col>
</lf>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" method="xml" version="1.0" indent="yes"/>
<!-- Catch-all templates -->
<xsl:template match="@*|text()">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="processing-instruction()">
<xsl:copy/>
</xsl:template>
<!-- delete spot from the top -->
<xsl:template match="spot[id[text()='_flare']]"/>
<!-- add spot to the bottom -->
<xsl:template match="snd">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="//spot[id[text()='_flare']]" mode="addToBottom"/>
</xsl:copy>
</xsl:template>
<xsl:template match="spot[id[text()='_flare']]" mode="addToBottom">
<lf>
<pos>
<xsl:apply-templates select="./posit/*"/>
</pos>
<col>#ffffff</col>
</lf>
</xsl:template>
</xsl:stylesheet>
I found the answer myself on the last question.
My xslt stylesheet is now:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="spot[id='_flare']"/>
<xsl:template match="snd">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select="../hs/spot[id='_flare']" mode="add"/>
</xsl:copy>
</xsl:template>
<xsl:template match="spot" mode="add">
<lf>
<pos>
<xsl:copy-of select="posit/pan | posit/tilt"/>
</pos>
<col>#ffffff</col>
</lf>
</xsl:template>
<xsl:template match="id"/>
<xsl:template match="hs/spot" >
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
<id> <xsl:value-of select="concat('Point',count(preceding::spot)+1)"/> </id>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
There might be a smarter way though ....
Based on michael.hor257k's solution, you can leave it unchanged and simply add one more template for handling the id's:
<xsl:template match="spot">
<xsl:copy>
<xsl:apply-templates select="@*|node()[local-name()!='id']"/>
<id>
<xsl:text>Point</xsl:text>
<xsl:value-of select="format-number(count(preceding-sibling::spot[not(id='_flare')])+1,'00')"/>
</id>
</xsl:copy>
</xsl:template>
The old id's will be ignored, and each element gets a new one, starting from "Point01".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.