Jump to content

Get Info From One Node To Apply To All Sub-nodes


rudd_eric@hotmail.com

Recommended Posts

Hi I'm in way over my head here .. VERY new to converting xml with xsl and then i got this huge xml-form that I need to convert in order to import to a database.I've been trying back and forth with "for-each" but soon found out that I need some inputfrom the experts :-) The the below XML form I need the info (actually only info from a few <fields> under each <card>)the <field>-info under <card> to be insertet for each <article> further below. each card can haveone or more <article>. On top of this, only <card>'s with <CARD langID="5"> should be extracted.(there are many different languages in the file)I need to import this to an excel spreadsheet, to each <article> under each <card> followed bythe info from <fields> should be one row.To further mess things up, the <articles> with <FIELD fieldName="Art nr" rowID="22776" langID="5">Art.-Nr.</FIELD>where text is text and not a number (or a matched string "Art nr" = "Art.-Nr.") should not be included... not possible maybe ?It could also drop the first <article> if there are more than one <article>.. if only one it has to be inlcuded.I tried to make a table with <td>'s from 1 to 20 and insert the info from each <field> in the <td> below to be able to copy the whole thing to excel. got all the info, but I'm clueless on how to get the "common info" from card-field under each article.MY xml-form: <CARD prodCardID="36005" orgCardID="36002" langID="5" language="German" productNo="" cardName="100347, DRAGSET PREMIUM"> <FIELDS> <FIELD name="Rubrik">BLINKER-SATZ PREMIUM</FIELD> <FIELD name="Beskrivning">* Blinker-Satz für Barsch, Hecht o.ä.</FIELD> <FIELD name="Bild/extratext"/> <FIELD name="Katalogbild">Original:W100347.eps</FIELD> <FIELD name="Nyhetsbild"/> <FIELD name="Beskrivning web">* Blinker-Satz für Barsch, Hecht o.ä.</FIELD> <FIELD name="Sökord">Blinker, Köder</FIELD> <FIELD name="Art nr ref">100347, 100348, 100349</FIELD> <FIELD name="Leverantör">STOXDAL</FIELD> <FIELD name="PC">HM</FIELD> <FIELD name="Sidnummer">6707</FIELD> <FIELD name="Nyhet/år">08</FIELD> <FIELD name="Webbild liten">Websmall/W100347.jpg</FIELD> <FIELD name="Webbild stor">Weblarge/W100347.jpg</FIELD> <FIELD name="webSubGroup">200</FIELD> <FIELD name="Web länk 1 rubrik"/> <FIELD name="Web länk 1"/> <FIELD name="Web länk 2 rubrik"/> <FIELD name="Web länk 2"/> <FIELD name="Web länk 3 rubrik"/> <FIELD name="Web länk 3"/> <FIELD name="Katalogbild 2">Original:W100348.eps</FIELD> <FIELD name="Katalogbild 3">Original:W100349.eps</FIELD> <FIELD name="Katalogbild 4"/> <FIELD name="Katalogbild 5"/> <FIELD name="Katalogbild 6"/> <FIELD name="Katalogbild 7"/> <FIELD name="Extra fält"/> <FIELD name="noweb"/> </FIELDS> <ARTICLES> <ARTICLE articleID="87947" cardID="36005" orgCardID="36002" tableID="6088"> <FIELD fieldName="Art nr" rowID="22762" langID="5">Art nr</FIELD> <FIELD fieldName="Art nr katalog" rowID="22762" langID="5">Art.-Nr.</FIELD> <FIELD fieldName="Typ" rowID="22762" langID="5">Typ</FIELD> <FIELD fieldName="Gram" rowID="22762" langID="5">Gew.</FIELD> <FIELD fieldName="Pris" rowID="22762" langID="5">Preis</FIELD> </ARTICLE> <ARTICLE articleID="87979" cardID="36005" orgCardID="36002" tableID="6088"> <FIELD fieldName="Art nr" rowID="22773" langID="5">100348</FIELD> <FIELD fieldName="Art nr katalog" rowID="22773" langID="5">100348</FIELD> <FIELD fieldName="Typ" rowID="22773" langID="5">Hecht</FIELD> <FIELD fieldName="Gram" rowID="22773" langID="5">12-18 gr</FIELD> <FIELD fieldName="Pris" rowID="22773" langID="5">11,95</FIELD> </ARTICLE> <ARTICLE articleID="87983" cardID="36005" orgCardID="36002" tableID="6088"> <FIELD fieldName="Art nr" rowID="22775" langID="5">100349</FIELD> <FIELD fieldName="Art nr katalog" rowID="22775" langID="5">100349</FIELD> <FIELD fieldName="Typ" rowID="22775" langID="5">Küste</FIELD> <FIELD fieldName="Gram" rowID="22775" langID="5">10-20 gr</FIELD> <FIELD fieldName="Pris" rowID="22775" langID="5">11,95</FIELD> </ARTICLE> <ARTICLE articleID="88273" cardID="36005" orgCardID="36002" tableID="6088"> <FIELD fieldName="Art nr" rowID="22846" langID="5">100347</FIELD> <FIELD fieldName="Art nr katalog" rowID="22846" langID="5">100347</FIELD> <FIELD fieldName="Typ" rowID="22846" langID="5">Barsch</FIELD> <FIELD fieldName="Gram" rowID="22846" langID="5">7-12 gr</FIELD> <FIELD fieldName="Pris" rowID="22846" langID="5">9,95</FIELD> </ARTICLE> </ARTICLES> </CARD>This <CARD> has 4 <ARTICLE> the first should not be includedEach of the <ARTICLE>'s <FIELD> should be followed by the info in the <FIELD>'s directly under >CARD>in this case for the first <ARTICLE> export should look like this;36002;100348;100348;Hecht;12-18 gr;11,95;BLINKER-SATZ PREMIUM;* Blinker-Satz für Barsch, Hecht o.ä.;Websmall/W100347.jpg;200This is after I've selected which <FIELD>'s to export from the <CARD> only need a few.Any bright heads that have any bright ideas on how to accomplish this ?!I hope I could explain it ok, my technical English is not all that good. :-)Tks.Eric

Link to comment
Share on other sites

I am afraid I have not been able to understand what you want to achieve.One sub problem seems to only process certain elements you can do that easily with e.g.

<xsl:apply-templates select="CARD[@langID = 5]"/>

or of course

<xsl:for-each select="CARD[@langID = 5]">   ...</xsl:for-each>

That way you would only process tthose CARD element(s) where the langID attribute is '5'.Other than that I am not sure what you want to achieve.Do you want pain text output from your stylesheet? Or HTML?Do you want to use XSLT 2.0 or 1.0?

Link to comment
Share on other sites

I am afraid I have not been able to understand what you want to achieve.One sub problem seems to only process certain elements you can do that easily with e.g.
<xsl:apply-templates select="CARD[@langID = 5]"/>

or of course

<xsl:for-each select="CARD[@langID = 5]">   ...</xsl:for-each>

That way you would only process tthose CARD element(s) where the langID attribute is '5'.Other than that I am not sure what you want to achieve.Do you want pain text output from your stylesheet? Or HTML?Do you want to use XSLT 2.0 or 1.0?

Hi .. tks for you answer.Sorry, as I said my technical English ( or English at all) is not all that good.I'll try a shorter version...Every CARD has FIELDS and ARTICLES The CARD/FIELDS/FIELD -elements are generic for ALL the ARTICLESSom <CARD> elements has only one <ARTICLE> under <ARTICLES>, othersseveral. I need the informastion in <field> under <CARD>/<FIELDS> added to all the <ARTICLES> /<ARTICLE> - elements.I'm going to import this to a database, so a CSV file is my goal. Tried to make a HTMl file and copy/paste info into Excel to do this, dont know how tooutput i.e. a ;-separeted txt-file.so in short, i need to add the info from <FIELDS> to all the ARTICLE-elements output toa single row for each article.Any better explained this time :-) ?!? Thanks again :-) Eric
Link to comment
Share on other sites

Please also state whether you want to use XSLT 2.0 (e.g. with Saxon or AltovaXML tools) or 1.0 (e.g. in the browser).As for outputting FIELD data, do you want to output the text contents of the FIELD elements? Or the attributes? Or both?What do you want to do with empty FIELD elements? Should an empty string (e.g. ;; or ,,) appear in the comma or semicolon separated list?

Link to comment
Share on other sites

If you use XSLT 2.0 then the following might help:

<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="2.0">    <xsl:output method="text"/>    <xsl:param name="sep" select="';'"/>  <xsl:param name="lf" select="'
'"/>    <xsl:template match="/">	<xsl:apply-templates select="*/CARD[@langID = 5]/ARTICLES/ARTICLE"/>  </xsl:template>    <xsl:template match="ARTICLE">	<xsl:value-of select="concat(string-join((@orgCardID, FIELD[node()], ../../FIELDS/FIELD[node()]), $sep), $lf)"/>  </xsl:template></xsl:stylesheet>

Even if you don't use XSLT 2.0 then the ../../FIELDS/FIELD should show you how to access the FIELDS/FIELD elements when processing an ARTICLE element.

Link to comment
Share on other sites

Please also state whether you want to use XSLT 2.0 (e.g. with Saxon or AltovaXML tools) or 1.0 (e.g. in the browser).As for outputting FIELD data, do you want to output the text contents of the FIELD elements? Or the attributes? Or both?What do you want to do with empty FIELD elements? Should an empty string (e.g. ;; or ,,) appear in the comma or semicolon separated list?
Oh.. forgot, sorry..Saxon :-) So, XSLT 2.0. Need the text elements only ..
Link to comment
Share on other sites

If you use XSLT 2.0 then the following might help:
<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="2.0">    <xsl:output method="text"/>    <xsl:param name="sep" select="';'"/>  <xsl:param name="lf" select="''"/>    <xsl:template match="/">	<xsl:apply-templates select="*/CARD[@langID = 5]/ARTICLES/ARTICLE"/>  </xsl:template>    <xsl:template match="ARTICLE">	<xsl:value-of select="concat(string-join((@orgCardID, FIELD[node()], ../../FIELDS/FIELD[node()]), $sep), $lf)"/>  </xsl:template></xsl:stylesheet>

Even if you don't use XSLT 2.0 then the ../../FIELDS/FIELD should show you how to access the FIELDS/FIELD elements when processing an ARTICLE element.

Tks again .. The. ../../FIELDS/FIELD[node()] will input match all nodes from FIELDS/FIELD with each ARTICLE ?And the "for-each" tag should go where ? If empty stings can be left out it would be perfect :-)Sorry if I seem "a bit" "green" when it comes to this .. but I really appreciate all the help !!!
Link to comment
Share on other sites

I don't think you need a for-each, the apply-templates and the string-join should suffice. If you use Saxon then try my posted stylesheet, it should output a line of semicolon separated values for each of your ARTICLE elements. You can change the separator (e.g. semicolon) by setting the parameter named 'sep'.The only problem is that the forum unfortunately has messed up the code of the stylesheet slightly, the param named lf is supposed to be defined as the string '& # 1 3 ; & # 10 ;', without the spaces between characters and digits.

Link to comment
Share on other sites

I don't think you need a for-each, the apply-templates and the string-join should suffice. If you use Saxon then try my posted stylesheet, it should output a line of semicolon separated values for each of your ARTICLE elements. You can change the separator (e.g. semicolon) by setting the parameter named 'sep'.The only problem is that the forum unfortunately has messed up the code of the stylesheet slightly, the param named lf is supposed to be defined as the string '& # 1 3 ; & # 10 ;', without the spaces between characters and digits.
Hi again .. sorry for late followup, I've been away a few days.Thanks again , I tried to correct the param named lf, with you info,but I dont get any output at all. <xsl:param name="lf" select="' & # 1 3; & # 1 0 ;'"/> ... right ?? (but without the spaces !) Using Oxygen xml editor with Saxon 6.5.5If I try saxon 9.1.0.7 I get a couple of errors reading the stylesheet.I'll try a command line "instant saxon" , maybe thats better ...I see you have put @orgCardID in the value of string , is it to output every uniqe @orgCardIDAnd one more thing ..The XML file looks like this:<GROUPS> <GROUP name="test">a lot of <CARD> -NODES here</GROUP></GROUPS>My question about the "for each" tag was if that was needed to process all <CARD> nodes or if youscript will read all as it is.Tks again !!!Eric
Link to comment
Share on other sites

The posted stylesheet is an XSLT 2.0 stylesheet so you need to run it with Saxon 8.9 or later. Saxon 9.1.0.7 should be fine.Saxon 6 is an XSLT 1.0 processor so using that with an XSLT 2.0 stylesheet will not work.If you get errors with Saxon 9.1.0.7 then you need to provide the details of errors if you want us to help fix them.As you have now explained what ancestors your CARD elements have the stylesheet needs to be amended so change that template with match="/" as follows:

  <xsl:template match="/">	<xsl:apply-templates select="GROUPS/GROUP[@name = 'test']/CARD[@langID = 5]/ARTICLES/ARTICLE"/>  </xsl:template>

You are right, the stylesheet outputs the attribute orgCardID at the beginning of each line as your posted result seems to contain that value. If you don't want that then simply change that template to e.g.

  <xsl:template match="ARTICLE">	<xsl:value-of select="concat(string-join((FIELD[node()], ../../FIELDS/FIELD[node()]), $sep), $lf)"/>  </xsl:template>

Link to comment
Share on other sites

The posted stylesheet is an XSLT 2.0 stylesheet so you need to run it with Saxon 8.9 or later. Saxon 9.1.0.7 should be fine.Saxon 6 is an XSLT 1.0 processor so using that with an XSLT 2.0 stylesheet will not work.If you get errors with Saxon 9.1.0.7 then you need to provide the details of errors if you want us to help fix them.As you have now explained what ancestors your CARD elements have the stylesheet needs to be amended so change that template with match="/" as follows:
  <xsl:template match="/">	<xsl:apply-templates select="GROUPS/GROUP[@name = 'test']/CARD[@langID = 5]/ARTICLES/ARTICLE"/>  </xsl:template>

You are right, the stylesheet outputs the attribute orgCardID at the beginning of each line as your posted result seems to contain that value. If you don't want that then simply change that template to e.g.

  <xsl:template match="ARTICLE">	<xsl:value-of select="concat(string-join((FIELD[node()], ../../FIELDS/FIELD[node()]), $sep), $lf)"/>  </xsl:template>

Get error with Saxon-SA 9.1.0.7 as follows:SystemID: D:\xml\saxon2\1.xmlSeverity: errorDescription: Cannot validate <CARD>: no element declaration availableStart location: 2:7URL: http://www.w3.org/TR/xslt20/#err-XTTE1510Saxon-B 9.1.0.7 gives no error and no output.
Link to comment
Share on other sites

I don't know about Saxon SA, and the error you get is about validation anyway. Unless you have a schema for the input XML and you want to validate the input before transforming it I don't think using the SA version has any benefits.As you don't get any output with Saxon B we will need to look at details of the XML input and the exact stylesheet you are using now so please post an input sample and the stylesheet you use when you get no output.

Link to comment
Share on other sites

I don't know about Saxon SA, and the error you get is about validation anyway. Unless you have a schema for the input XML and you want to validate the input before transforming it I don't think using the SA version has any benefits.As you don't get any output with Saxon B we will need to look at details of the XML input and the exact stylesheet you are using now so please post an input sample and the stylesheet you use when you get no output.
My XML and XSL
I don't know about Saxon SA, and the error you get is about validation anyway. Unless you have a schema for the input XML and you want to validate the input before transforming it I don't think using the SA version has any benefits.As you don't get any output with Saxon B we will need to look at details of the XML input and the exact stylesheet you are using now so please post an input sample and the stylesheet you use when you get no output.
My XML-file : <?xml version="1.0" encoding="UTF-8"?> <GROUPS> <GROUP name="test"> <CARD orgCardID="36002" langID="5"> <FIELDS> <FIELD name="Rubrik">SEXKANTSPILK</FIELD> <FIELD name="Beskrivning">Rostfri, snabbt sjunkande.</FIELD> <FIELD name="Bild/extratext"/> <FIELD name="Katalogbild">Original:F100350-351-352.eps</FIELD> <FIELD name="Nyhetsbild"/> <FIELD name="Beskrivning web">Rostfri, snabbt sjunkande.</FIELD> <FIELD name="Sökord">SEXKANTSPILK</FIELD> <FIELD name="Art nr ref">100350, 100351, 100352</FIELD> <FIELD name="Leverantör">STOXDAL</FIELD> <FIELD name="PC">HM</FIELD> <FIELD name="Sidnummer">6707</FIELD> <FIELD name="Nyhet/år">W08</FIELD> <FIELD name="Webbild liten">Websmall/F100350-351-352.jpg</FIELD> <FIELD name="Webbild stor">Weblarge/F100350-351-352.jpg</FIELD> <FIELD name="webSubGroup">200</FIELD> <FIELD name="Web länk 1 rubrik"/> <FIELD name="Web länk 1"/> <FIELD name="Web länk 2 rubrik"/> <FIELD name="Web länk 2"/> <FIELD name="Web länk 3 rubrik"/> <FIELD name="Web länk 3"/> <FIELD name="Katalogbild 2"/> <FIELD name="Katalogbild 3"/> <FIELD name="Katalogbild 4"/> <FIELD name="Katalogbild 5"/> <FIELD name="Katalogbild 6"/> <FIELD name="Katalogbild 7"/> <FIELD name="Extra fält"/> <FIELD name="noweb"/> </FIELDS> <ARTICLES> <ARTICLE articleID="87984" cardID="36006" orgCardID="36006" tableID="6091"> <FIELD fieldName="Art nr" rowID="22776" langID="1">Art nr</FIELD> <FIELD fieldName="Art nr katalog" rowID="22776" langID="1">Art nr</FIELD> <FIELD fieldName="Gram" rowID="22776" langID="1">Vikt</FIELD> <FIELD fieldName="Pris" rowID="22776" langID="1">Pris</FIELD> </ARTICLE> <ARTICLE articleID="87985" cardID="36006" orgCardID="36006" tableID="6091"> <FIELD fieldName="Art nr" rowID="22777" langID="1">100351</FIELD> <FIELD fieldName="Art nr katalog" rowID="22777" langID="1">100351</FIELD> <FIELD fieldName="Gram" rowID="22777" langID="1">200 gr</FIELD> <FIELD fieldName="Pris" rowID="22777" langID="1">49:-</FIELD> </ARTICLE> <ARTICLE articleID="87986" cardID="36006" orgCardID="36006" tableID="6091"> <FIELD fieldName="Art nr" rowID="22778" langID="1">100352</FIELD> <FIELD fieldName="Art nr katalog" rowID="22778" langID="1">100352</FIELD> <FIELD fieldName="Gram" rowID="22778" langID="1">300 gr</FIELD> <FIELD fieldName="Pris" rowID="22778" langID="1">59:-</FIELD> </ARTICLE> <ARTICLE articleID="88274" cardID="36006" orgCardID="36006" tableID="6091"> <FIELD fieldName="Art nr" rowID="22848" langID="1">100350</FIELD> <FIELD fieldName="Art nr katalog" rowID="22848" langID="1">100350</FIELD> <FIELD fieldName="Gram" rowID="22848" langID="1">100 gr</FIELD> <FIELD fieldName="Pris" rowID="22848" langID="1">39:-</FIELD> </ARTICLE> </ARTICLES> </CARD> <CARD orgCardID="36003" langID="4"> <FIELDS> <FIELD name="Rubrik">SLUKSETT</FIELD> <FIELD name="Beskrivning">Sluksett for abbor, gjedde, eller kystfiske.</FIELD> <FIELD name="Bild/extratext"/> <FIELD name="Katalogbild">Original:W100347.eps</FIELD> <FIELD name="Nyhetsbild"/> <FIELD name="Beskrivning web">Sluksett for abbor, gjedde, eller kystfiske.</FIELD> <FIELD name="Sökord">Fiskekrok, abbor, gjedde, kyst, sluk</FIELD> <FIELD name="Art nr ref">100347, 100348, 100349</FIELD> <FIELD name="Leverantör">STOXDAL</FIELD> <FIELD name="PC">HM</FIELD> <FIELD name="Sidnummer">6707</FIELD> <FIELD name="Nyhet/år">08</FIELD> <FIELD name="Webbild liten">Websmall/W100347.jpg</FIELD> <FIELD name="Webbild stor">Weblarge/W100347.jpg</FIELD> <FIELD name="webSubGroup">200</FIELD> <FIELD name="Web länk 1 rubrik"/> <FIELD name="Web länk 1"/> <FIELD name="Web länk 2 rubrik"/> <FIELD name="Web länk 2"/> <FIELD name="Web länk 3 rubrik"/> <FIELD name="Web länk 3"/> <FIELD name="Katalogbild 2">Original:W100348.eps</FIELD> <FIELD name="Katalogbild 3">Original:W100349.eps</FIELD> <FIELD name="Katalogbild 4"/> <FIELD name="Katalogbild 5"/> <FIELD name="Katalogbild 6"/> <FIELD name="Katalogbild 7"/> <FIELD name="Extra fält"/> <FIELD name="noweb"/> </FIELDS> <ARTICLES> <ARTICLE articleID="87945" cardID="36003" orgCardID="36002" tableID="6088"> <FIELD fieldName="Art nr" rowID="22762" langID="4">Art nr</FIELD> <FIELD fieldName="Art nr katalog" rowID="22762" langID="4">Art nr</FIELD> <FIELD fieldName="Typ" rowID="22762" langID="4">Type</FIELD> <FIELD fieldName="Gram" rowID="22762" langID="4">Vekt</FIELD> <FIELD fieldName="Pris" rowID="22762" langID="4">Pris</FIELD> </ARTICLE> <ARTICLE articleID="87977" cardID="36003" orgCardID="36002" tableID="6088"> <FIELD fieldName="Art nr" rowID="22773" langID="4">100348</FIELD> <FIELD fieldName="Art nr katalog" rowID="22773" langID="4">100348</FIELD> <FIELD fieldName="Typ" rowID="22773" langID="4">Gjedde</FIELD> <FIELD fieldName="Gram" rowID="22773" langID="4">12-18 gr</FIELD> <FIELD fieldName="Pris" rowID="22773" langID="4">132,-</FIELD> </ARTICLE> <ARTICLE articleID="87981" cardID="36003" orgCardID="36002" tableID="6088"> <FIELD fieldName="Art nr" rowID="22775" langID="4">100349</FIELD> <FIELD fieldName="Art nr katalog" rowID="22775" langID="4">100349</FIELD> <FIELD fieldName="Typ" rowID="22775" langID="4">Kyst</FIELD> <FIELD fieldName="Gram" rowID="22775" langID="4">10-20 gr</FIELD> <FIELD fieldName="Pris" rowID="22775" langID="4">111,-</FIELD> </ARTICLE> <ARTICLE articleID="88271" cardID="36003" orgCardID="36002" tableID="6088"> <FIELD fieldName="Art nr" rowID="22846" langID="4">100347</FIELD> <FIELD fieldName="Art nr katalog" rowID="22846" langID="4">100347</FIELD> <FIELD fieldName="Typ" rowID="22846" langID="4">Abbor</FIELD> <FIELD fieldName="Gram" rowID="22846" langID="4">7-12 gr</FIELD> <FIELD fieldName="Pris" rowID="22846" langID="4">111,-</FIELD> </ARTICLE> </ARTICLES> </CARD></GROUP></GROUPS>......................................<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output method="text"/> <xsl:param name="sep" select="';'"/> <xsl:param name="lf" select="' '"/> <xsl:template match="/"> <xsl:apply-templates select="GROUPS/GROUP[@name = 'test']/CARD[@langID = 5]/ARTICLES/ARTICLE"/> </xsl:template> <xsl:template match="ARTICLE"> <xsl:value-of select="concat(string-join((FIELD[node()], ../../FIELDS/FIELD[node()]), $sep), $lf)"/> </xsl:template> </xsl:stylesheet>Is the encoding (UTF-8) a possible problem ?Eric
Link to comment
Share on other sites

I can't reproduce the problem. I have used Saxon 9.1.0.7 Java from the command line and it outputs the following data:

Art nr;Art nr;Vikt;Pris;SEXKANTSPILK;Rostfri, snabbt sjunkande.;Original:F100350-351-352.eps;Rostfri, snabbt sjunkande.;SEXKANTSPILK;100350, 100351, 100352;STOXDAL;HM;6707;W08;Websmall/F100350-351-352.jpg;Weblarge/F100350-351-352.jpg;200100351;100351;200 gr;49:-;SEXKANTSPILK;Rostfri, snabbt sjunkande.;Original:F100350-351-352.eps;Rostfri, snabbt sjunkande.;SEXKANTSPILK;100350, 100351, 100352;STOXDAL;HM;6707;W08;Websmall/F100350-351-352.jpg;Weblarge/F100350-351-352.jpg;200100352;100352;300 gr;59:-;SEXKANTSPILK;Rostfri, snabbt sjunkande.;Original:F100350-351-352.eps;Rostfri, snabbt sjunkande.;SEXKANTSPILK;100350, 100351, 100352;STOXDAL;HM;6707;W08;Websmall/F100350-351-352.jpg;Weblarge/F100350-351-352.jpg;200100350;100350;100 gr;39:-;SEXKANTSPILK;Rostfri, snabbt sjunkande.;Original:F100350-351-352.eps;Rostfri, snabbt sjunkande.;SEXKANTSPILK;100350, 100351, 100352;STOXDAL;HM;6707;W08;Websmall/F100350-351-352.jpg;Weblarge/F100350-351-352.jpg;200

Stylesheet is as follows:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"><xsl:output method="text"/><xsl:param name="sep" select="';'"/><xsl:param name="lf" select="'
'"/><xsl:template match="/"><xsl:apply-templates select="GROUPS/GROUP[@name = 'test']/CARD[@langID = 5]/ARTICLES/ARTICLE"/></xsl:template><xsl:template match="ARTICLE"><xsl:value-of select="concat(string-join((FIELD[node()], ../../FIELDS/FIELD[node()]), $sep), $lf)"/></xsl:template></xsl:stylesheet>

where the select attribute value of xsl:param name="lf" is meant to be '& # 13 ; & # 10 ;' without the spaces.I am not sure why you don't get any output, you might want to ask in an Oxygen forum if you use that to run the transformation.

Link to comment
Share on other sites

I can't reproduce the problem. I have used Saxon 9.1.0.7 Java from the command line and it outputs the following data:
Art nr;Art nr;Vikt;Pris;SEXKANTSPILK;Rostfri, snabbt sjunkande.;Original:F100350-351-352.eps;Rostfri, snabbt sjunkande.;SEXKANTSPILK;100350, 100351, 100352;STOXDAL;HM;6707;W08;Websmall/F100350-351-352.jpg;Weblarge/F100350-351-352.jpg;200100351;100351;200 gr;49:-;SEXKANTSPILK;Rostfri, snabbt sjunkande.;Original:F100350-351-352.eps;Rostfri, snabbt sjunkande.;SEXKANTSPILK;100350, 100351, 100352;STOXDAL;HM;6707;W08;Websmall/F100350-351-352.jpg;Weblarge/F100350-351-352.jpg;200100352;100352;300 gr;59:-;SEXKANTSPILK;Rostfri, snabbt sjunkande.;Original:F100350-351-352.eps;Rostfri, snabbt sjunkande.;SEXKANTSPILK;100350, 100351, 100352;STOXDAL;HM;6707;W08;Websmall/F100350-351-352.jpg;Weblarge/F100350-351-352.jpg;200100350;100350;100 gr;39:-;SEXKANTSPILK;Rostfri, snabbt sjunkande.;Original:F100350-351-352.eps;Rostfri, snabbt sjunkande.;SEXKANTSPILK;100350, 100351, 100352;STOXDAL;HM;6707;W08;Websmall/F100350-351-352.jpg;Weblarge/F100350-351-352.jpg;200

Stylesheet is as follows:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"><xsl:output method="text"/><xsl:param name="sep" select="';'"/><xsl:param name="lf" select="''"/><xsl:template match="/"><xsl:apply-templates select="GROUPS/GROUP[@name = 'test']/CARD[@langID = 5]/ARTICLES/ARTICLE"/></xsl:template><xsl:template match="ARTICLE"><xsl:value-of select="concat(string-join((FIELD[node()], ../../FIELDS/FIELD[node()]), $sep), $lf)"/></xsl:template></xsl:stylesheet>

where the select attribute value of xsl:param name="lf" is meant to be '& # 13 ; & # 10 ;' without the spaces.I am not sure why you don't get any output, you might want to ask in an Oxygen forum if you use that to run the transformation.

I tried command line java , worked !! :-) Fantastic :-) I'm not sure it pulled out all the fields correcly .. the txt -file does a line break in the middle...I want to import it to excel so should be one long line for each... I'll test a couple of things.THANK U !!!!!!! you really know your XML / XSL and I learned a lot from this !Eric !!
Link to comment
Share on other sites

Thought I had it but not quite..In some of the <card> elements there are some text-info with line breaks.Cant seem to get rid of them. I need one <ARTICLE> pr line even if the <FIELD name="Beskrivning"> has line-breaks.

<FIELD name="Beskrivning">Teleskop-Rute aus Glasfaser. Länge 210 cm.                        Zusammengeschoben 43 cm. Für Wurfgewichte 10-30 g. Keramik-Ringe schützen                        die Leine. Haspelrolle. 100 m Sehne (0,30 mm).</FIELD>                    <FIELD name="Bild/extratext"/>                    <FIELD name="Katalogbild">Original:F74054.eps</FIELD>                    <FIELD name="Nyhetsbild"/>                    <FIELD name="Beskrivning web">Teleskop-Rute aus Glasfaser. Keramik-Ringe                        schützen die Leine. Länge: 210 cm Zusammengeschoben: 43 cm Für Wurfgewichte:                        10-30 g Haspelrolle: 100 m Sehne: 0,30 mm</FIELD>

Also to produce output that I can import to excel I need to keep all nodes even if empty.Tried: <xsl:param name="default" select="'null'" /> but it still does not output empty fieldsOr even better, can I somewhere choose which <field>'s I want to output.only output spesific field names <field name="xxx">Tks. again.

Link to comment
Share on other sites

To output emtpy FIELD elements as well change

<xsl:value-of select="concat(string-join((FIELD[node()], ../../FIELDS/FIELD[node()]), $sep), $lf)"/>

to

<xsl:value-of select="concat(string-join((FIELD, ../../FIELDS/FIELD), $sep), $lf)"/>

To replace line breaks with a space use

<xsl:value-of select="concat(string-join((FIELD/normalize-space(.), ../../FIELDS/FIELD/normalize-space(.)), $sep), $lf)"/>

If you want to output only specific FIELD elements then you can add a predicate e.g.

<xsl:value-of select="concat(string-join((FIELD[@name = 'foo' or @name = 'bar']/normalize-space(.), ../../FIELDS/FIELD[@name = 'whatever' or @name = 'whatelse']/normalize-space(.)), $sep), $lf)"/>

Link to comment
Share on other sites

To output emtpy FIELD elements as well change
<xsl:value-of select="concat(string-join((FIELD[node()], ../../FIELDS/FIELD[node()]), $sep), $lf)"/>

to

<xsl:value-of select="concat(string-join((FIELD, ../../FIELDS/FIELD), $sep), $lf)"/>

To replace line breaks with a space use

<xsl:value-of select="concat(string-join((FIELD/normalize-space(.), ../../FIELDS/FIELD/normalize-space(.)), $sep), $lf)"/>

If you want to output only specific FIELD elements then you can add a predicate e.g.

<xsl:value-of select="concat(string-join((FIELD[@name = 'foo' or @name = 'bar']/normalize-space(.), ../../FIELDS/FIELD[@name = 'whatever' or @name = 'whatelse']/normalize-space(.)), $sep), $lf)"/>

Thats it ! .. you won't belive how many xml/xsl -websites/pages I've read to try to figure it out.Works great !! Thank you again ... :-)Eric
Link to comment
Share on other sites

Well, I found one more little thing that can be done manually but wouldhelp a lot to do in the script. :-)The number of <ARTICLE> - <FIELD>'s are not consistent.Some times only one, sometimes 2 and sometimes more.

 <ARTICLE articleID="18053" cardID="17471" orgCardID="17468" tableID="1536">            <FIELD fieldName="Art nr" rowID="4516" langID="5">76000-0007</FIELD>            <FIELD fieldName="Art nr katalog" rowID="4516" langID="5">76000-7</FIELD>            <FIELD fieldName="Typ" rowID="4516" langID="5">SILVA 58 Schwarz</FIELD>            <FIELD fieldName="Pris" rowID="4516" langID="5">59,00</FIELD>Or<ARTICLE articleID="67172" cardID="17478" orgCardID="17476" tableID="4842">            <FIELD fieldName="Art nr" rowID="16961" langID="3">76000-0068</FIELD>            <FIELD fieldName="Art nr" rowID="16961" langID="3">76000-68</FIELD>            <FIELD fieldName="Pris" rowID="16961" langID="3">2250,-</FIELD>          </ARTICLE>

That makes for a bit of a manual job in the excel when the file is imported.Can it be set to add "blanks" so that the first is "Art nr" and the last is "pris"and the ones in between fill out blanks if there is anything to fill in og leave it empty if not ?? Tricky one maybe ? Also .. <FIELD name="Art nr"> sometimes has the text >Art nr</FIELD>Like this: <FIELD fieldName="Art nr">Art nr</FIELD>Is there a code to match fieldName="Art nr" to the node-txt , and IF the node-txtis "Art nr" skip import of that <ARTICLE> Getting to be a bit advanced maybe, and can be done manually but would be interesting to see if its possible to do som "magic" on this as well :-) Eric

Link to comment
Share on other sites

Skipping certain ARTICLE elements should be easy:

<xsl:template match="/">  <xsl:apply-templates select="GROUPS/GROUP[@name = 'test']/CARD[@langID = 5]/ARTICLES/ARTICLE[not(FIELD[@name = 'Art nr'][. = 'Art nr'])]"/></xsl:template>

The other problem is more difficult to solve, somehow the stylesheet needs to have a complete list of the FIELDs you want to output. Is there always one ARTICLE having all FIELD elements, and is that always the first (or last)? Or how do we know which FIELD we need to output? If that information is not in the input then we need to put it in the stylesheet.

Link to comment
Share on other sites

The other problem is more difficult to solve, somehow the stylesheet needs to have a complete list of the FIELDs you want to output. Is there always one ARTICLE having all FIELD elements, and is that always the first (or last)? Or how do we know which FIELD we need to output? If that information is not in the input then we need to put it in the stylesheet.
I had a closer look at the files (14 large xml files)... it seems the last part can be a bit of a problem. The FIELD under ARTICLE is not very consistent, i.e. the ART NR is sometimes missing completely, other times written i small letters . This means that the ART NR is not always in the same place.It works fine with pulling only the ART NR and PRIS from the file. Maybe its possible to SKIP output of an ARTICLE if the ART NR og PRIS does not exist ? ? Works great with the new part: not(FIELD[@fieldName = 'Art nr'][. = 'Art nr'])] TKS again ! :-)Can the same be done with Art nr not existing ... og Art nr NOT a number ?? I must say its amazing what can be done with so few lines of code... even if the code is a bit complex (at least to me !)Eric
Link to comment
Share on other sites

What kind of ARTICLE elements exactly do you want to skip? Those where there is no FIELD element with attribute fieldName="Art nr"? That would be

<xsl:template match="/">  <xsl:apply-templates select="GROUPS/GROUP[@name = 'test']/CARD[@langID = 5]/ARTICLES/ARTICLE[not(FIELD[@name = 'Art nr']) and not(FIELD[@name = 'Art nr'][. = 'Art nr'])]"/></xsl:template>

It is also possible to check for a certain number format or even character format (with the help of regular expressions) but to implement that you need to explain with samples and/or a precise description of what kind of formats you want to process and what kind of formats you want to script. Is that only positive integer numbers or also negative ones or even double numbers?

Link to comment
Share on other sites

What kind of ARTICLE elements exactly do you want to skip? Those where there is no FIELD element with attribute fieldName="Art nr"? That would be
<xsl:template match="/">  <xsl:apply-templates select="GROUPS/GROUP[@name = 'test']/CARD[@langID = 5]/ARTICLES/ARTICLE[not(FIELD[@name = 'Art nr']) and not(FIELD[@name = 'Art nr'][. = 'Art nr'])]"/></xsl:template>

It is also possible to check for a certain number format or even character format (with the help of regular expressions) but to implement that you need to explain with samples and/or a precise description of what kind of formats you want to process and what kind of formats you want to script. Is that only positive integer numbers or also negative ones or even double numbers?

That took care of a whole lot of the fields...Now a few lines have <FIELD fieldName="Art nr" rowID="7972" langID="1"> , No text statement, but has the fieldName so its included. ! So they come out wrong. Tried [not(FIELD[@name = 'Art nr'])][. = ''])]With nothing between ' ' , but it didnt help.Have insertet [not(FIELD[@name = 'Art nr'])] and [not(FIELD[@name = 'Pris'])] Works great when these are missing :-)
Link to comment
Share on other sites

You could try
[not(FIELD[@name = 'Art nr'][not(normalize-space())])]

to ignore 'FIELD' elements with 'name' attribute being 'Art nr' but containing nothing but white space or no contents at all.

I was a bit quick with the [not(FIELD[@name = 'Art nr'])] and [not(FIELD[@name = 'Pris'])] what happens is that it ONLY outputs the fields that are missing Art nr og Pris :-OThought I had it working ;-)The code-line now lookes like this:<xsl:apply-templates select="GROUPS/GROUP/CARDS/CARD[@langID = 4 ]/ARTICLES/ARTICLE[not(FIELD[@fieldName = 'Art nr'][. = 'Art nr'])][not(FIELD[@fieldName = 'Art nr'][. = 'art nr'])][not(FIELD[@name = 'Art nr'][not(normalize-space())])][not(FIELD[@fieldName = 'Art nr'])][not(FIELD[@fieldName = 'Pris'])]"/>
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...