Design XSLT to create a comma separated value list - xslt

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>

Related

How to get duplicate record as single record in xslt

I am struggling to get desired output result in xslt:
I want something Like I have 2 records in each records i have multiple child node I have to check if the child element values are duplicated in one record or not if yes i should only create 1 record with respect to duplicate record and remaining records for unique ones,
My input file looks like:
<Records count="2">
<Record id="parentRecord">
<Record id="childRecord1">
<Record id="childRecord2">
<Field id="childRecord2Field">Technology Asset Management</Field>
</Record>
</Record>
<Record id="childRecord1">
<Record id="childRecord2">
<Field id="childRecord2Field1">Inadequate Information Security Practices</Field>
</Record>
</Record>
<Record id="childRecord1">
<Record id="childRecord2">
<Field id="childRecord2Field1">Inadequate Information Security Practices</Field>
</Record>
</Record>
</Record>
<Record id="parentRecord">
<Record id="childRecord1">
<Record id="childRecord2">
<Field id="childRecord2Field">Technology Asset Management</Field>
</Record>
</Record>
<Record id="childRecord1">
<Record id="childRecord2">
<Field id="childRecord2Field1">Inadequate Information Security Practices</Field>
</Record>
</Record>
<Record id="childRecord1">
<Record id="childRecord2">
<Field id="childRecord2Field">Technology Asset Management</Field>
</Record>
</Record>
</Record>
</Records>
I am Expecting :
<Records>
<Record id="parentRecord">
<Record id="childRecord1">
<Record id="childRecord2">
<Field id="childRecord2Field">Technology Asset Management</Field>
</Record>
</Record>
<Record id="childRecord1">
<Record id="childRecord2">
<Field id="childRecord2Field1">Inadequate Information Security Practices</Field>
</Record>
</Record>
</Record>
<Record id="parentRecord">
<Record id="childRecord1">
<Record id="childRecord2">
<Field id="childRecord2Field">Technology Asset Management</Field>
</Record>
</Record>
<Record id="childRecord1">
<Record id="childRecord2">
<Field id="childRecord2Field1">Inadequate Information Security Practices</Field>
</Record>
</Record>
</Records>
Here is my xslt:
<xsl:template match="Records">
<Records>
<xsl:for-each select="Record[id='parentRecord']">
<xsl:variable name="MatchedChildRecord2Value" select="Record/Record/Field[id='childRecord2Field']"> //I am trying to store all the field values in paraent node
<xsl:for-each select="Record/Record/Field[id=childRecord2']/">
<xsl:choose>
<xsl:when test=".=$MatchedChildRecord2Value">
//Nothing I am doing
</xsl:when>
<xsl:otherwise>
<Record>
<Record id="childRecord1">
<Record id="childRecord2">
<Field>FieldRecordvalue</Field>
</Record>
</Record>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</Records>
</xsl:template>
Could you please help me out
I've tried it this way with XSLT3. I don't get the same result as what you indicated that you wanted, but I don't understand your result as there are duplicates within your result.
I've added an additional attribute count in order to show how many duplicates were folded into the result.
I get this result:
<Records>
<Record id="parentRecord" count="2">
<Record id="childRecord1" count="6">
<Record id="childRecord2" count="6">
<Field id="childRecord2Field" count="3">Technology Asset Management</Field>
<Field id="childRecord2Field1" count="3">Inadequate Information Security Practices</Field>
</Record>
</Record>
</Record>
</Records>
using this xslt3 stylesheet:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output indent="yes" />
<xsl:template match="/Records">
<xsl:copy >
<xsl:call-template name="groupRecords" >
<xsl:with-param name="currentGroup" select="Record" />
</xsl:call-template >
</xsl:copy>
</xsl:template>
<xsl:template name="groupRecords" >
<xsl:param name="currentGroup" as="element()*" />
<xsl:for-each-group select="$currentGroup/self::Record" group-by="#id" >
<Record id="{current-grouping-key()}" count="{count(current-group())}" >
<xsl:call-template name="groupRecords" >
<xsl:with-param name="currentGroup" select="current-group()/*" />
</xsl:call-template>
</Record>
</xsl:for-each-group>
<xsl:for-each-group select="$currentGroup/self::Field" group-by="concat(#id, '##', text())" >
<Field id="{current-group()[1]/#id}" count="{count(current-group())}">{(current-group()/text())[1]}</Field>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>

How to access a specific node in XSL

silly question but hoping I can get some help here, I need to access specific node in XSL, the XML I am provided with looks like the below, can someone give me an idea what my XSL should look like in order to access the content of the node 'Value' I cannot no matter how i try reach that node!- any help appreciated!!!! :
<?xml version="1.0" encoding="UTF-8" ?>
<CrystalReport xmlns="urn:crystal-reports:schemas:report-detail"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:crystal-reports:schemas:report-detail http://www.businessobjects.com/products/xml/CR2008Schema.xsd">
<Group Level="1">
<Group Level="2">
<Details Level="3">
<Section SectionNumber="1">
<Field Name="Field5" FieldName="{ARTransaction.Transactions}">
<FormattedValue>0.00</FormattedValue>
<Value>0.00</Value>
</Field>
<Field Name="Field15" FieldName="{ARTransaction.PostingDate}">
<FormattedValue>8/1/2016</FormattedValue>
<Value>2016-08-01</Value>
</Field>
<Field Name="Field14" FieldName="{ARTransaction.AuditTrail}">
<FormattedValue>2016083100154</FormattedValue>
<Value>2016083100154</Value>
</Field>
<Field Name="Field13" FieldName="{ARTransaction.JobN}">
<FormattedValue>-25043</FormattedValue>
<Value>-25043</Value>
</Field>
<Field Name="Field11" FieldName="{Customer.CustomerName}">
<FormattedValue>First Church of Christ</FormattedValue>
<Value>First Church of Christ</Value>
</Field>
<Field Name="Field7" FieldName="{ARTransaction.CustomerN}">
<FormattedValue>13157</FormattedValue>
<Value>13157</Value>
</Field>
<Field Name="Field6" FieldName="{ARTransaction.InvoiceN}">
<FormattedValue>25043</FormattedValue>
<Value>25043</Value>
</Field>
<Field Name="SalesmanN1" FieldName="{ARTransaction.SalesmanN}">
<FormattedValue>22</FormattedValue>
<Value>22</Value>
</Field>
</Section>
</Details>
</Group>
</Group>
</Group>
<ReportFooter> </ReportFooter>
XSL :
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:element name="CrystalReport">
<xsl:attribute name="xsi:schemaLocation">http://www.w3.org/2001/XMLSchema-instance</xsl:attribute>
<xsl:attribute name="version">1.2</xsl:attribute>
</xsl:element>
<xsl:element name="DR">
<xsl:value-of select="Group/Group/Details/Section/Field[#Name='Field13']/Value"/>
</xsl:element>
</xsl:template>
The main problem with your attempt is that it ignores the default namespace of the source XML.
You need to declare the namespace in your stylesheet, assign it a prefix, and use that prefix when addressing the elements in the source XML. For example, the following stylesheet:
XSL 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="urn:crystal-reports:schemas:report-detail"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/ns1:CrystalReport">
<DR>
<xsl:value-of select="ns1:Group/ns1:Group/ns1:Details/ns1:Section/ns1:Field[#Name='Field13']/ns1:Value"/>
</DR>
</xsl:template>
</xsl:stylesheet>
when applied to a well-formed input such as:
XML
<CrystalReport xmlns="urn:crystal-reports:schemas:report-detail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:crystal-reports:schemas:report-detail http://www.businessobjects.com/products/xml/CR2008Schema.xsd">
<Group Level="1">
<Group Level="2">
<Details Level="3">
<Section SectionNumber="1">
<Field Name="Field5" FieldName="{ARTransaction.Transactions}">
<FormattedValue>0.00</FormattedValue>
<Value>0.00</Value>
</Field>
<Field Name="Field15" FieldName="{ARTransaction.PostingDate}">
<FormattedValue>8/1/2016</FormattedValue>
<Value>2016-08-01</Value>
</Field>
<Field Name="Field14" FieldName="{ARTransaction.AuditTrail}">
<FormattedValue>2016083100154</FormattedValue>
<Value>2016083100154</Value>
</Field>
<Field Name="Field13" FieldName="{ARTransaction.JobN}">
<FormattedValue>-25043</FormattedValue>
<Value>-25043</Value>
</Field>
<Field Name="Field11" FieldName="{Customer.CustomerName}">
<FormattedValue>First Church of Christ</FormattedValue>
<Value>First Church of Christ</Value>
</Field>
<Field Name="Field7" FieldName="{ARTransaction.CustomerN}">
<FormattedValue>13157</FormattedValue>
<Value>13157</Value>
</Field>
<Field Name="Field6" FieldName="{ARTransaction.InvoiceN}">
<FormattedValue>25043</FormattedValue>
<Value>25043</Value>
</Field>
<Field Name="SalesmanN1" FieldName="{ARTransaction.SalesmanN}">
<FormattedValue>22</FormattedValue>
<Value>22</Value>
</Field>
</Section>
</Details>
</Group>
</Group>
</CrystalReport>
will return:
Result
<?xml version="1.0" encoding="UTF-8"?>
<DR>-25043</DR>
Note: If you're using an XSLT 2.0 processor, you can declare a xpath-default-namespace attribute and do away with the prefix.

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

XSL Grouping Problem

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>