XSL Grouping Problem - xslt

Using XSLT 1.0 - I have the following xml and I an trying to perform the following
Group By the first Field where id="1923" if the value attribute is the same
and average all the fields with id="3095" using the value attribute
and average all the fields with id="3095" using the value attribute
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="Trans.xsl"?>
<Results>
<List count="6">
<Record contentId="1017835" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="1" parentRow="" >
<Field id="1923" type="1" value="Test 1"></Field>
<Field id="3095" type="4" valueID="3809" value="1" parentId="3809" parentName="5" ></Field>
<Field id="3096" type="4" valueID="3809" value="1" parentId="3809" parentName="5" ></Field>
</Record>
<Record contentId="1017828" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="2" parentRow="" >
<Field id="1923" type="1" value="Test 2"></Field>
<Field id="3095" type="4" valueID="729" value="2" parentId="729" parentName="2" ></Field>
<Field id="3096" type="4" valueID="3809" value="5" parentId="3809" parentName="5" ></Field>
</Record>
<Record contentId="1017978" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="3" parentRow="" >
<Field id="1923" type="1" value="Test 3"></Field>
<Field id="3095" type="4" valueID="3808" value="4" parentId="3808" parentName="4" ></Field>
<Field id="3096" type="4" valueID="3808" value="4" parentId="3808" parentName="4" ></Field>
</Record>
<Record contentId="1035463" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="4" parentRow="" >
<Field id="1923" type="1" value="Test 2"></Field>
<Field id="3095" type="4" valueID="3808" value="4" parentId="3808" parentName="4" ></Field>
<Field id="3096" type="4" valueID="730" value="3" parentId="730" parentName="3" ></Field>
</Record>
<Record contentId="1017985" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="5" parentRow="" >
<Field id="1923" type="1" value="Test 1"></Field>
<Field id="3095" type="4" valueID="113690" value="10" parentId="113690" parentName="10" ></Field>
<Field id="3096" type="4" valueID="113690" value="10" parentId="113690" parentName="10" ></Field>
</Record>
<Record contentId="1017835" finalFlag="True" levelId="" moduleId="152" primarySortId="" secondarySortId="" parentId="0" row="6" parentRow="" >
<Field id="1923" type="1" value="Test 1"></Field>
<Field id="3095" type="4" valueID="3809" value="5" parentId="3809" parentName="5" ></Field>
<Field id="3096" type="4" valueID="3809" value="5" parentId="3809" parentName="5" ></Field>
</Record>
</List>
</Results>
Trying to produce the following using trans.xsl:
<Records>
<Data>
<Text1923>Test 1</Text1923>
<Avg3095>5.33</Avg3095>
<Avg3096>5.33</Avg3096>
</Data>
<Data>
<Text1923>Test 2</Text1923>
<Avg3095>3</Avg3095>
<Avg3096>4</Avg3096>
</Data>
<Data>
<Text1923>Test 3</Text1923>
<Avg3095>4</Avg3095>
<Avg3096>4</Avg3096>
</Data>
</Records>

Here is a simple XSLT 1.0 solution using the Muenchian Grouping Method:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kFieldById" match="Field"
use="#id"/>
<xsl:key name="kField1923"
match="Field[#id='1923']" use="#value"/>
<xsl:template match="/">
<Records>
<xsl:for-each select=
"key('kFieldById', '1923')
[generate-id()
=
generate-id(key('kField1923',
#value
)
[1]
)
]
">
<Data>
<Text1923>
<xsl:value-of select="#value"/>
</Text1923>
<xsl:variable name="vSubfield3095" select=
"key('kField1923',#value)
/../Field[#id='3095']
"/>
<xsl:variable name="vSubfield3096" select=
"key('kField1923',#value)
/../Field[#id='3096']
"/>
<Avg3095>
<xsl:value-of select=
"sum($vSubfield3095/#value)
div
count($vSubfield3095)
"/>
</Avg3095>
<Avg3096>
<xsl:value-of select=
"sum($vSubfield3096/#value)
div
count($vSubfield3096)
"/>
</Avg3096>
</Data>
</xsl:for-each>
</Records>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document, the wanted, correct resul is produced:
<Records>
<Data>
<Text1923>Test 1</Text1923>
<Avg3095>5.333333333333333</Avg3095>
<Avg3096>5.333333333333333</Avg3096>
</Data>
<Data>
<Text1923>Test 2</Text1923>
<Avg3095>3</Avg3095>
<Avg3096>4</Avg3096>
</Data>
<Data>
<Text1923>Test 3</Text1923>
<Avg3095>4</Avg3095>
<Avg3096>4</Avg3096>
</Data>
</Records>

Related

Design XSLT to create a comma separated value list

I am not a code developer, my tool has a restriction in this case with the default XSLT. I have tried editing the default XSLT and creating a new one, but i am not getting the desired output. So, I want to write a custom XSLT and I need your help on that.
I have tried applying template and xsl:value-of select="/Records/Record/Record/Record/Field[#id='23425']" separator=", "/>, but it's not working.
Source XML:
<?xml version="1.0" encoding="UTF-16"?>
<Records count="2">
<Record contentId="490422" levelId="49" levelGuid="efcc872e-8014-4d1f-8830-6a63d0bd51d9" moduleId="71" parentId="0">
<Record contentId="490431" levelId="397" levelGuid="9a560130-79ad-4250-9901-3eafc4e0e799" moduleId="600" parentId="0">
<Record contentId="490425" levelId="398" levelGuid="2ef4fb6a-092e-471e-b481-1a6380022e10" moduleId="601" parentId="0">
<Field id="23426" guid="dd028a89-90de-4ca0-9d08-c9d2d0c47a19" type="1">Program 1</Field>
<Field id="23425" guid="0b389b7f-efc3-4933-92c3-0388e0ceb4e7" type="1">user1</Field>
<Field id="23422" guid="83c5d064-5c90-45f7-a2c7-635b42a69bdd" type="6">490425</Field>
</Record>
<Record contentId="490426" levelId="398" levelGuid="2ef4fb6a-092e-471e-b481-1a6380022e10" moduleId="601" parentId="0">
<Field id="23426" guid="dd028a89-90de-4ca0-9d08-c9d2d0c47a19" type="1">Program 2</Field>
<Field id="23425" guid="0b389b7f-efc3-4933-92c3-0388e0ceb4e7" type="1">user2</Field>
<Field id="23422" guid="83c5d064-5c90-45f7-a2c7-635b42a69bdd" type="6">490426</Field>
</Record>
<Field id="23429" guid="2bc40ece-8e0e-4f11-9e67-7d15e4021746" type="1">SErvice 4</Field>
</Record>
<Field id="120" guid="bd1c1f0e-47df-4a21-bbd7-473557d8a278" type="1">Device 1</Field>
</Record>
<Record contentId="490423" levelId="49" levelGuid="efcc872e-8014-4d1f-8830-6a63d0bd51d9" moduleId="71" parentId="0">
<Record contentId="490432" levelId="397" levelGuid="9a560130-79ad-4250-9901-3eafc4e0e799" moduleId="600" parentId="0">
<Record contentId="490427" levelId="398" levelGuid="2ef4fb6a-092e-471e-b481-1a6380022e10" moduleId="601" parentId="0">
<Field id="23426" guid="dd028a89-90de-4ca0-9d08-c9d2d0c47a19" type="1">Copy of Program 1</Field>
<Field id="23425" guid="0b389b7f-efc3-4933-92c3-0388e0ceb4e7" type="1">user5</Field>
<Field id="23422" guid="83c5d064-5c90-45f7-a2c7-635b42a69bdd" type="6">490427</Field>
</Record>
<Record contentId="490428" levelId="398" levelGuid="2ef4fb6a-092e-471e-b481-1a6380022e10" moduleId="601" parentId="0">
<Field id="23426" guid="dd028a89-90de-4ca0-9d08-c9d2d0c47a19" type="1">Copy of Program 2</Field>
<Field id="23425" guid="0b389b7f-efc3-4933-92c3-0388e0ceb4e7" type="1">user4</Field>
<Field id="23422" guid="83c5d064-5c90-45f7-a2c7-635b42a69bdd" type="6">490428</Field>
</Record>
<Record contentId="490429" levelId="398" levelGuid="2ef4fb6a-092e-471e-b481-1a6380022e10" moduleId="601" parentId="0">
<Field id="23426" guid="dd028a89-90de-4ca0-9d08-c9d2d0c47a19" type="1">Copy of Program 3</Field>
<Field id="23425" guid="0b389b7f-efc3-4933-92c3-0388e0ceb4e7" type="1">user5</Field>
<Field id="23422" guid="83c5d064-5c90-45f7-a2c7-635b42a69bdd" type="6">490429</Field>
</Record>
<Field id="23429" guid="2bc40ece-8e0e-4f11-9e67-7d15e4021746" type="1">Service 2</Field>
</Record>
<Record contentId="490431" levelId="397" levelGuid="9a560130-79ad-4250-9901-3eafc4e0e799" moduleId="600" parentId="0">
<Record contentId="490425" levelId="398" levelGuid="2ef4fb6a-092e-471e-b481-1a6380022e10" moduleId="601" parentId="0">
<Field id="23426" guid="dd028a89-90de-4ca0-9d08-c9d2d0c47a19" type="1">Program 1</Field>
<Field id="23425" guid="0b389b7f-efc3-4933-92c3-0388e0ceb4e7" type="1">user1</Field>
<Field id="23422" guid="83c5d064-5c90-45f7-a2c7-635b42a69bdd" type="6">490425</Field>
</Record>
<Record contentId="490426" levelId="398" levelGuid="2ef4fb6a-092e-471e-b481-1a6380022e10" moduleId="601" parentId="0">
<Field id="23426" guid="dd028a89-90de-4ca0-9d08-c9d2d0c47a19" type="1">Program 2</Field>
<Field id="23425" guid="0b389b7f-efc3-4933-92c3-0388e0ceb4e7" type="1">user2</Field>
<Field id="23422" guid="83c5d064-5c90-45f7-a2c7-635b42a69bdd" type="6">490426</Field>
</Record>
<Field id="23429" guid="2bc40ece-8e0e-4f11-9e67-7d15e4021746" type="1">SErvice 4</Field>
</Record>
<Field id="120" guid="bd1c1f0e-47df-4a21-bbd7-473557d8a278" type="1">Device 2</Field>
</Record>
</Records>
Needed Output/Transformed XML:
<?xml version="1.0" encoding="UTF-8"?>
<ArcherRecords xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.archer-tech.com/">
<ArcherRecord>
<Device_Name>Device 1</Device_Name>
<Programs>
<Field_id>490425</Field_id>
</Programs>
<Programs>
<Field_id>490426</Field_id>
</Programs>
<ProgExecutive>user 1,user 2<ProgExecutive>
</ArcherRecord>
<ArcherRecord>
<Device_Name>Device 2</Device_Name>
<Programs>
<Field_id>490425</Field_id>
</Programs>
<Programs>
<Field_id>490426</Field_id>
</Programs>
<Programs>
<Field_id>490427</Field_id>
</Programs>
<Programs>
<Field_id>490428</Field_id>
</Programs>
<Programs>
<Field_id>490429</Field_id>
</Programs>
<ProgExecutive>user 3,user 4,user 5, user 1, user 2<ProgExecutive>
</ArcherRecord>
</ArcherRecords>
Below XSLT is working for me
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
xmlns="http://www.archer-tech.com/">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Records">
<ArcherRecords >
<xsl:apply-templates select="Record" />
</ArcherRecords>
</xsl:template>
<xsl:template match="Record[#levelId='49']">
<ArcherRecord>
<xsl:element name="Device_Name">
<xsl:value-of select="Field[#id='120']" />
</xsl:element>
<xsl:element name="Calc_Prog_Executive">
<xsl:for-each select="Record/Record/Field[#id='23425']">
<xsl:value-of select="." />
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
</xsl:element>
<Programs>
<xsl:apply-templates select="Record/Record" />
</Programs>
</ArcherRecord>
</xsl:template>
<xsl:template match="Record/Record/Record">
<Tracking_Id>
<xsl:apply-templates select="#contentId" />
</Tracking_Id>
</xsl:template>
</xsl:stylesheet>

How to add a list of product in a view?

i'm using odoo 8 and i want to know how to add a page that contains list of product and theire quantity in a view, to mention in a request for intervention which products we are going to modify. In that way we can estimate how costs every intervention
view.xml
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_intervention_form" model="ir.ui.view">
<field name="name">cmms.intervention.form</field>
<field name="model">cmms.intervention</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Intervention request" version="7.0">
<header>
<button name="action_broadcast" type="object" string="Déffuser mail" icon="STOCK_REDO"/>
<button name="action_done" states="draft" string="Valider" type="object" icon="gtk-apply"/>
<button name="action_cancel" states="done," string="Annuler" type="object" icon="gtk-cancel"/>
<button name="action_draft" states="cancel" string="Remettre en brouillon" type="object" icon="terp-stock_effects-object-colorize"/>
<field name="state" widget="statusbar" />
</header>
<sheet>
<group>
<group>
<field name="name" select="1" />
<field name="user_id" select="1" colspan="1" />
<field name="user2_id" />
<field name="priority" />
<field name="state_machine" />
<field name="product_id"/>
</group>
<group>
<field name="type" select="1" colspan="1" />
<field name="equipment_id" select="1" colspan="1" />
<field name="date_inter" />
<field name="date_end" />
</group>
</group>
<newline />
<notebook colspan="1">
<page string="Motif d'intervention">
<field name="motif" />
</page>
<page string="Observation">
<field name="observation" />
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
</data>
</openerp>
You should add a field One2many to the page and then define the tree view, somethnig like:
<field name="fieldOne2many">
<tree editable="bottom">
<field name="product_id"/>
<field name="quantity"/>
</tree>
</field>
But first, you must define it in models.py and create the class related to the one2many, that contains quantity and product_id.
Regards.

GPX import to Filemaker Pro using XSL stylesheet

I know about GPSbabel and have used it for transforming GPX files into CSV that I can then import into Filemaker Pro for manipulation. However, I'd like to be able to import GPX files more simply & neatly into FMP and hoped I could write a XSL stylesheet to convert the GPX form of XML to the FMPXMLRESULT grammar.
I'm looking at GPX files from Garmin Foretrex, Dakota, Nuvi & GPSmap296 devices. My latest attempt at a XSL stylesheet (using snippets cribbed from various examples) looks like:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml"/>
<xsl:template match="trkseg">
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
<ERRORCODE>0</ERRORCODE>
<PRODUCT BUILD="01-25-2011" NAME="FileMaker" VERSION="ProAdvanced 11.0v3"/>
<DATABASE DATEFORMAT="Yyyy-m-d" LAYOUT="" NAME="gpx_import_test.fp7" RECORDS="{#count}"
TIMEFORMAT="k:mm:ss "/>
<METADATA>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="ele" TYPE="NUMBER"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="lat" TYPE="NUMBER"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="lon" TYPE="NUMBER"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="time_text" TYPE="TEXT"/>
</METADATA>
<RESULTSET FOUND="#count">
<xsl:for-each select="trkpt">
<ROW MODID="0" RECORDID="{position()}">
<COL>
<DATA>
<xsl:value-of select="lat"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="lon"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="ele"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="time_text"/>
</DATA>
</COL>
</ROW>
</xsl:for-each>
</RESULTSET>
</FMPXMLRESULT>
</xsl:template>
</xsl:stylesheet>
When I try to use the above stylesheet, FMP complains "XML parsing error: invalid document structure".
I'd welcome any suggestions - I guess I'm making some very simple and obvious error.
regards
Rowland
Here is a snipped version of a typical GPX file from a Garmin Dakota 20 that I am trying to import.
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gpx xmlns="http://www.topografix.com/GPX/1/1"
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"
xmlns:wptx1="http://www.garmin.com/xmlschemas/WaypointExtension/v1"
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
creator="Dakota 20" version="1.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1
http://www.topografix.com/GPX/1/1/gpx.xsd
http://www.garmin.com/xmlschemas/GpxExtensions/v3
http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd
http://www.garmin.com/xmlschemas/WaypointExtension/v1
http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd
http://www.garmin.com/xmlschemas/TrackPointExtension/v1
http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd">
<metadata>
<link href="http://www.garmin.com">
<text>Garmin International</text>
</link>
<time>2011-10-21T16:55:50Z</time>
</metadata>
<trk>
<name>Current Track: 20 OCT 2011 10:31</name>
<extensions>
<gpxx:TrackExtension>
<gpxx:DisplayColor>Black</gpxx:DisplayColor>
</gpxx:TrackExtension>
</extensions>
<trkseg>
<trkpt lat="51.6084605176" lon="-2.2182025295">
<ele>43.40</ele>
<time>2011-10-20T09:31:44Z</time>
</trkpt>
<trkpt lat="51.6084605176" lon="-2.2182025295">
<ele>47.24</ele>
<time>2011-10-20T09:31:53Z</time>
</trkpt>
</trkseg>
</trk>
</gpx>
Several problems here. One is this:
<xsl:template match="trkseg">
You do not start at the root, so the XSLT processor will process the root and all other elements using default rules (which are to output the value of the element). This may add extra text around FMPXMLRESULT. To fix it we need to do something like:
<xsl:template match="/">
<xsl:for-each select="//trkseg/trkpt"> <!-- or use a full path -->
...
</xsl:for-each>
This is not enough because trkseg is not just trkseg, it's trkseg in the GPX namespace. Without proper namespace declaration the stylesheet won't find the elements at all. And the final problem is that lat and lon are attributes and you need to refer to them as #lat and #lon. Here's the working XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gpx="http://www.topografix.com/GPX/1/1"
exclude-result-prefixes="gpx">
<xsl:output indent="yes" method="xml"/>
<xsl:template match="/">
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
<ERRORCODE>0</ERRORCODE>
<PRODUCT BUILD="01-25-2011" NAME="FileMaker" VERSION="ProAdvanced 11.0v3"/>
<DATABASE DATEFORMAT="Yyyy-m-d"
LAYOUT="" NAME="gpx_import_test.fp7" RECORDS="{#count}"
TIMEFORMAT="k:mm:ss "/>
<METADATA>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="ele" TYPE="NUMBER"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="lat" TYPE="NUMBER"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="lon" TYPE="NUMBER"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="time" TYPE="TEXT"/>
</METADATA>
<RESULTSET FOUND="count(//gpx:trkseg/gpx:trkpt)">
<xsl:for-each select="//gpx:trkseg/gpx:trkpt">
<ROW MODID="0" RECORDID="{position()}">
<COL>
<DATA>
<xsl:value-of select="#lat"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="#lon"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="gpx:ele"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="gpx:time"/>
</DATA>
</COL>
</ROW>
</xsl:for-each>
</RESULTSET>
</FMPXMLRESULT>
</xsl:template>
</xsl:stylesheet>
Here is a xslt file to read out only the waypoints, not the tracks: By
the way: I added the fields time, name, sym and type to the import. If
not needed, delete the corresponding lines in this file.
Copy and store the text below the dotted line in a file named
"yourchoice.xslt" where "yourchoice" might be any name you want and
use this as a xslt transformation file in filemaker.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gpx="http://www.topografix.com/GPX/1/1"
exclude-result-prefixes="gpx">
<xsl:output indent="yes" method="xml"/>
<xsl:template match="/">
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
<ERRORCODE>0</ERRORCODE>
<PRODUCT BUILD="01-25-2011" NAME="FileMaker" VERSION="ProAdvanced 11.0v3"/>
<DATABASE DATEFORMAT="Yyyy-m-d"
LAYOUT="" NAME="gpx_import_test.fp7" RECORDS="{#count}"
TIMEFORMAT="k:mm:ss "/>
<METADATA>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="latitude" TYPE="NUMBER"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="longitude" TYPE="NUMBER"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="elevation" TYPE="NUMBER"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="time" TYPE="TEXT"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="name" TYPE="TEXT"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="sym" TYPE="TEXT"/>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="type" TYPE="TEXT"/>
</METADATA>
<RESULTSET FOUND="count(gpx:wpt)">
<xsl:for-each select="gpx:wpt">
<ROW MODID="0" RECORDID="{position()}">
<COL>
<DATA>
<xsl:value-of select="#lat"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="#lon"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="gpx:ele"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="gpx:time"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="gpx:name"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="gpx:sym"/>
</DATA>
</COL>
<COL>
<DATA>
<xsl:value-of select="gpx:type"/>
</DATA>
</COL>
</ROW>
</xsl:for-each>
</RESULTSET>
</FMPXMLRESULT>
</xsl:template>
</xsl:stylesheet>

Using XSL to get all tags before a tag with given contents occurs

maybe somebody take me some advice how to correct this program. I should take from fields number before +. Sometimes this field comes at the 17th line(field id 17), sometimes 14, 19 and etc...Others fields are also filled. Right now my program takes this number from field id 17. How to correct it?
Data example:
<document>
<line id="0">
<field id="0"><![CDATA[MAR5555]]></field>
<field id="1"><![CDATA[12314124141241]]></field>
<field id="2"><![CDATA[AAS]]></field>
<field id="3"><![CDATA[FOR12312]]></field>
<field id="4"/>
<field id="5"/>
<field id="6"/>
<field id="7"/>
<field id="8"/>
<field id="9"/>
<field id="10"/>
<field id="11"/>
<field id="12"/>
<field id="13"/>
<field id="14"/>
<field id="15"/>
<field id="16"/>
<field id="17"><![CDATA[0072972+1313113123123]]></field>
<field id="18"><![CDATA[5353]]></field>
<field id="19"><![CDATA[444444]]></field>
<field id="20"/>
<field id="21"/>
</line>
<line id="1">
<field id="0"><![CDATA[MAR6435]]></field>
<field id="1"><![CDATA[car123]]></field>
<field id="2"><![CDATA[sds]]></field>
<field id="3"><![CDATA[fest]]></field>
<field id="4"/>
<field id="5"/>
<field id="6"/>
<field id="7"/>
<field id="8"/>
<field id="9"/>
<field id="10"/>
<field id="11"/>
<field id="12"/>
<field id="13"/>
<field id="14"/>
<field id="15"><![CDATA[0000062+0dadasd]]></field>
<field id="16"><![CDATA[0d2]]></field>
<field id="17"><![CDATA[cccc]]></field>
<field id="18"/>
<field id="19"><![CDATA[000000]]></field>
<field id="20"/>
<field id="21"/>
</line>
<line id="2">
<field id="0"><![CDATA[MAR6435]]></field>
<field id="1"><![CDATA[sss]]></field>
<field id="2"><![CDATA[1231231]]></field>
<field id="3"><![CDATA[45123]]></field>
<field id="4"/>
<field id="5"/>
<field id="6"/>
<field id="7"/>
<field id="8"/>
<field id="9"/>
<field id="10"/>
<field id="11"/>
<field id="12"/>
<field id="13"/>
<field id="14"/>
<field id="15"><![CDATA[0000062+0sdsd]]></field>
<field id="16"><![CDATA[0f2]]></field>
<field id="17"><![CDATA[843252dsd]]></field>
<field id="18"/>
<field id="19"><![CDATA[000000]]></field>
<field id="20"/>
<field id="21"/>
</line>
</document>
My program example:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kLine" match="line" use="substring-before(field[#id='17'],'+')"/>
<xsl:template match="/*">
<document>
<xsl:apply-templates select="line[contains(field[#id='0'], 'MAR')][count(. | key('kLine', substring-before(field[#id='17'],'+'))[1]) = 1]"/>
</document>
</xsl:template>
<xsl:template match="line">
<type-MAR>
<document>
<xsl:value-of select="substring-before(field[#id='17'],'+')"/>
</document>
</type-MAR>
</xsl:template>
</xsl:stylesheet>
Result:
<type-MAR>
<document>
0072972
</document>
<document>
0000062
</document>
</type-MAR>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kLine" match="line" use="
substring-before(
field[contains(., '+')]
,'+'
)"/>
<xsl:template match="/*">
<document>
<xsl:apply-templates select="
line
[contains(field[#id='0'], 'MAR')]
[count(
. | key(
'kLine',
substring-before(
field[contains(., '+')]
,'+')
)
[1]
) = 1
]"/>
</document>
</xsl:template>
<xsl:template match="line">
<type-MAR>
<document>
<xsl:value-of select="
substring-before(
field[contains(., '+')],
'+'
)
"/>
</document>
</type-MAR>
</xsl:template>
</xsl:stylesheet>
Well-formed XML output against your sample is:
<document>
<type-MAR>
<document>0072972</document>
</type-MAR>
<type-MAR>
<document>0000062</document>
</type-MAR>
</document>

how to use ELEMENT: xsl:key?

HI all,
I should to generate this xml file:
<document>
<line id="0">
<field id="0"><![CDATA[MAR5555]]></field>
<field id="1"><![CDATA[something]]></field>
<field id="2"><![CDATA[something]]></field>
<field id="3"><![CDATA[something12123]]></field>
<field id="4"/>
<field id="5"/>
<field id="6"/>
<field id="7"/>
<field id="8"/>
<field id="9"/>
<field id="10"/>
<field id="11"/>
<field id="12"/>
<field id="13"/>
<field id="14"/>
<field id="15"/>
<field id="16"/>
<field id="17"><![CDATA[0072972+1313113123123]]></field>
<field id="18"><![CDATA[5353]]></field>
<field id="19"><![CDATA[444432323]]></field>
<field id="20"/>
<field id="21"/>
</line>
<line id="1">
<field id="0"><![CDATA[MAR6435]]></field>
<field id="1"><![CDATA[car123]]></field>
<field id="2"><![CDATA[sds]]></field>
<field id="3"><![CDATA[fest]]></field>
<field id="4"/>
<field id="5"/>
<field id="6"/>
<field id="7"/>
<field id="8"/>
<field id="9"/>
<field id="10"/>
<field id="11"/>
<field id="12"/>
<field id="13"/>
<field id="14"/>
<field id="15"><![CDATA[0000062+0dadasd]]></field>
<field id="16"><![CDATA[032]]></field>
<field id="17"><![CDATA[23242442]]></field>
<field id="18"/>
<field id="19"><![CDATA[000000]]></field>
<field id="20"/>
<field id="21"/>
</line>
<line id="2">
<field id="0"><![CDATA[MAR6435]]></field>
<field id="1"><![CDATA[sss]]></field>
<field id="2"><![CDATA[Something111]]></field>
<field id="3"><![CDATA[something111]]></field>
<field id="4"/>
<field id="5"/>
<field id="6"/>
<field id="7"/>
<field id="8"/>
<field id="9"/>
<field id="10"/>
<field id="11"/>
<field id="12"/>
<field id="13"/>
<field id="14"/>
<field id="15"><![CDATA[0000062+0sdsd]]></field>
<field id="16"><![CDATA[022]]></field>
<field id="17"><![CDATA[23444444]]></field>
<field id="18"/>
<field id="19"><![CDATA[000000]]></field>
<field id="20"/>
<field id="21"/>
</line>
</document>
My programs looks:
<xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kLine" match="line" use="substring-before(field[contains(., '+')],'+')"/>
<xsl:template match="/*">
<document>
<xsl:apply-templates select="line[contains(field[#id='0'], 'MAR')][count( . | key('kLine',substring-before(field[contains(., '+')],'+'))[1]) = 1]"/>
</document>
</xsl:template>
<xsl:template match="line">
<type-MAR>
<document>
<xsl:value-of select="substring-before(field[contains(., '+')],'+')"/>
</document>
<!-- For each document-->
<line>
<LineNumber>
<xsl:value-of select="position()"/>
</LineNumber>
<LineItem>
<xsl:value-of select="'should be fielled number of after two fields which contain symbol + '"/>
</LineItem>
</line>
<!-- For each document-->
</type-MAR>
</xsl:template>
</xsl:stylesheet>
I'm stuck, taking LineItem number after field id which contains symbol '+'. for example if I know that 'field id = 17' has + symbol, when after two rows I will have LineItem and do calculating I mean if 'field id = 17' when 'field id = 17+2', if 'field id = 16' then 'field id = 18' and so on. but now when field with symbol '+' are not defining, I can't to do it. Also if I use 'key', i want to ask how to use correct cycle "for each", to calculate number of lines. Result should be:
<document>
<type-MAR>
<document>0072972</document>
<line>
<LineNumber>1</LineNumber>
<LineItem>444432323</LineItem>
</line>
</type-MAR>
<type-MAR>
<document>0000062</document>
<line>
<LineNumber>1</LineNumber>
<LineItem>23242442</LineItem>
<LineNumber>2</LineNumber>
<LineItem>23444444</LineItem>
</line>
</type-MAR>
</document>
I solve it by self. maybe my question was not clearly.
first off all to found path to field after document number I use Following sibling. to select all needed LineItem I use "variable name", finally program looks:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kLine" match="line" use="substring-before(field[contains(., '+')],'+')"/>
<xsl:template match="/*">
<document>
<xsl:apply-templates select="line[contains(field[#id='0'], 'MAR')][count( . | key('kLine',substring-before(field[contains(., '+')],'+'))[1]) = 1]"/>
</document>
</xsl:template>
<xsl:template match="line">
<xsl:variable name="doc_code" select="substring-before(field[contains(., '+')],'+')"/>
<type-MAR>
<document>
<xsl:value-of select="substring-before(field[contains(., '+')],'+')"/>
</document>
<xsl:for-each select="//line[substring-before(field[contains(., '+')],'+')=$doc_code]">
<line>
<LineNumber>
<xsl:value-of select="position()"/>
</LineNumber>
<LineItem>
<xsl:value-of select="field[contains(., '+')]/following-sibling::field[2]"/>
</LineItem>
</line>
</xsl:for-each>
</type-MAR>
</xsl:template>
</xsl:stylesheet>
Best regards