How to access a specific node in XSL - xslt

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.

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>

EXSLT str:replace

Im having issues getting my XML to transform correctly using the EXSLT str:replace template.
Here is my XML:
<XML>
<Item>
<Field>
<Name>ID</Name>
<Value>98765</Value>
</Field>
<Field>
<Name>ParentID</Name>
<Value>10002</Value>
</Field>
<Field>
<Name>Type</Name>
<Value>content</Value>
</Field>
<Field>
<Name>Name</Name>
<Value>TestAPI Course</Value>
</Field>
<Field>
<Name>URL</Name>
<Value></Value>
</Field>
<Field>
<Name>Description</Name>
<Value>a description</Value>
</Field>
<Field>
<Name>DateBegin</Name>
<Value>2012-04-04T00:00:00.000-07:00</Value>
</Field>
<Field>
<Name>DateEnd</Name>
<Value>2012-04-04T00:00:00.000-08:00</Value>
</Field>
<Field>
<Name>DateCreated</Name>
<Value>2012-04-03T00:00:00.000-07:00</Value>
</Field>
<Field>
<Name>DateModified</Name>
<Value>2012-04-04T00:00:00.000-06:00</Value>
</Field>
</Item>
Here is my XSL:
<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings" extension-element-prefixes="str" version="1.0">
<xsl:import href="C:\inetpub\wwwroot\LMSConnector\LMS\XSL\str.xsl"/>
<xsl:template match="/Items">
<xsl:call-template name="str:replace">
<xsl:with-param name="string" select="Field/Name"/>
<xsl:with-param name="search" select="ID"/>
<xsl:with-param name="replace" select="sco-id"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
My problem is that I just get a XML document header and nothing else, but nothing else? I dont think I am far off a working solution and the problems probably lie in the values i am setting for the "match" parameter on the template, and the select parameters within the call-template with-param nodes.
Any help would be appreciated.
Mike
You are trying to match <xsl:template match="/Items">, however your XML contains <Item> elements, not <Items>.
EDIT
Is this what you are trying to do?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings" extension-element-prefixes="str">
<xsl:import href="http://delicious-library-export.googlecode.com/svn/trunk/str/str.xsl"/>
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/Item/Field/Name/text()">
<xsl:call-template name="str:replace">
<xsl:with-param name="string" select="."/>
<xsl:with-param name="search" select="'ID'"/>
<xsl:with-param name="replace" select="'sco-id'"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Result:
<?xml version="1.0" encoding="utf-8"?>
<Item>
<Field>
<Name>sco-id</Name>
<Value>98765</Value>
</Field>
<Field>
<Name>Parentsco-id</Name>
<Value>10002</Value>
</Field>
<Field>
<Name>Type</Name>
<Value>content</Value>
</Field>
<Field>
<Name>Name</Name>
<Value>TestAPI Course</Value>
</Field>
<Field>
<Name>URL</Name>
<Value/>
</Field>
<Field>
<Name>Description</Name>
<Value>a description</Value>
</Field>
<Field>
<Name>DateBegin</Name>
<Value>2012-04-04T00:00:00.000-07:00</Value>
</Field>
<Field>
<Name>DateEnd</Name>
<Value>2012-04-04T00:00:00.000-08:00</Value>
</Field>
<Field>
<Name>DateCreated</Name>
<Value>2012-04-03T00:00:00.000-07:00</Value>
</Field>
<Field>
<Name>DateModified</Name>
<Value>2012-04-04T00:00:00.000-06:00</Value>
</Field>
</Item>

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

Retrieve data from a different fields, where a landmark is a symbol

i have data, which looks like:
<line id="1">
<field id="1">324</field id="1">
<field id="2">abc</field id="2">
.................................
.................................
.................................
<field id="11">324321</field id="11">
<field id="12"
><![CDATA[6256812+0000140000000990000000000009900000000004058002C]]></field>
</line id="1">
<line id="2">
<field id="1">324</field id="1">
<field id="2">abc</field id="2">
.................................
.................................
.................................
<field id="8">324321</field id="11">
<field id="9"
><![CDATA[6256813+0000040000000890000000000008900000000003648002C]]></field>
</line id="2">
<line id="3">
<field id="1">324fsf</field id="1">
<field id="2">abcdf</field id="2">
.................................
.................................
.................................
<field id="12">32432s1</field id="11">
<field id="13"
><![CDATA[6256812+0000060000000750000000000007500000000003074002C]]></field>
</line id="3">
<line id="4">
<field id="1">3fsfa24</field id="1">
<field id="2">abasc</field id="2">
.................................
.................................
.................................
<field id="18">32fasf4321</field id="11">
<field id="19"
><![CDATA[6256837+0000010000000650000000000006500000000002664003C]]></field>
</line id="5">
I need to take number before landmark '+'.
<xsl:choose>
<xsl:when test="string(field[#id='9'])">
<xsl:value-of select="number(substring(field[#id='10'], 1,7))"/>
</xsl:when>
<xsl:when test="string(field[#id='11'])">
<xsl:value-of select="number(substring(field[#id='12'], 1,7))"/>
</xsl:when>
<xsl:when test="string(field[#id='17'])">
<xsl:value-of select="number(substring(field[#id='17'], 1,7))"/>
</xsl:when>
</xsl:choose>
maybe there is more right decision?
The proper XSLT way of doing this (push style processing):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="field[contains('|9|13|19|', concat('|',#id, '|'))]">
<xsl:value-of select="substring-before(.,'+')"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
when this transformation is applied on the provided XML document (corrected from being severely malformed):
<t>
<line id="1">
<field id="12"><![CDATA[6256812+0000140000000990000000000009900000000004058002C]]></field>
</line>
<line id="2">
<field id="9"><![CDATA[6256813+0000040000000890000000000008900000000003648002C]]></field>
</line>
<line id="3">
<field id="13"><![CDATA[6256812+0000060000000750000000000007500000000003074002C]]></field>
</line>
<line id="4">
<field id="19"><![CDATA[6256837+0000010000000650000000000006500000000002664003C]]></field>
</line>
</t>
the wanted, correct result is produced:
6256813
6256812
6256837
Do note: There is not even a single conditional xslt instruction in the transformation.
Use the substring-before function. You can use it to get the text before the first +
I'd also recommend using a separate template for each condition:
<xsl:template match="field[#id='9']">
<xsl:value-of select="substring-before(../field[#id='10'],'+')" />
</xsl:template>
Or something similar depending on the context.
Looks like a bad, brittle design to me. If you're going to rely on positional logic to parse the record, why not abandon XML and use EDI or another record-based format?
You're not using XML for what it's good for here. Tags are metadata that describe the stream. You lost it when you went to this design.
I'd recommend either using XML in a better way or going all the way to a position-based record scheme.