Importing ODK XML file to MS Access using XLST transformation - ms-access

I'm trying to import a submission.xml file generated from an ODK survey into Access. I'm using the 'XML import' function in MS Access and need to transform the data so that the each data set of a node that will be imported to a table will contain the ID of the survey.
I have a XML with the survey data that looks like this:
<SoLa_Tu_Insp_2016-03-13 id="SOLA-160313"
instanceID="uuid:63c27738-df02-4298-9090-7ab96d4e1ab2"
submissionDate="2016-04-08T02:11:47.600Z"
isComplete="true"
markedAsCompleteDate="2016-04-08T02:13:12.322Z"
xmlns="http://opendatakit.org/submissions">
<start>2016-04-08T23:47:50.615Z</start>
<end>2016-04-08T02:11:30.954Z</end>
<deviceid>353375050176865</deviceid>
<telnr />
<insp>
<objekt>25</objekt>
<objdel>212</objdel>
<objdel-tx>Bronstunneln</objdel-tx>
<datum>2016-04-08</datum>
<sign>MFR RLS</sign>
<anm>8</anm>
</insp>
<skdr>
<skd>
<metod>100</metod>
<ts>
<ts-nr>523</ts-nr>
<ts-typskada>Lucka - Lös - Takelement</ts-typskada>
<ts-kdel>15</ts-kdel>
<ts-kelem>1530</ts-kelem>
<ts-mtrl>13</ts-mtrl>
<ts-typ>35</ts-typ>
<ts-orsak>999</ts-orsak>
<ts-aktivitet>87</ts-aktivitet>
<ts-enhet>st</ts-enhet>
<ts-aktivitet-tx>Åtdragning</ts-aktivitet-tx>
<ts-mangd>1.0000000000</ts-mangd>
</ts>
<ovr>
<ovr-kdel />
<ovr-kdel-tx />
<ovr-kelem />
<ovr-kelem-tx />
<ovr-mtrl />
<ovr-mtrl-tx />
<ovr-typ />
<ovr-typ-tx />
<ovr-orsak />
<ovr-aktivitet />
<ovr-aktivitet-tx />
<ovr-enhet />
<ovr-mangd />
</ovr>
<kdel>15</kdel>
<kelem>1530</kelem>
<mtrl>13</mtrl>
<typ>35</typ>
<orsak>999</orsak>
<skd-tx>Gång/inspektionsbrygga etc / Lucka/dörr / Rostfritt stål / Lös / Övrigt</skd-tx>
<tk>3</tk>
<anm>Luckan håller på att ramla av</anm>
<aktivitet>87</aktivitet>
<mangd>1</mangd>
<enhet>st</enhet>
<sekt1>675</sekt1>
<sekt2 />
<lage>VT</lage>
<lage-tx />
<bildskada>1460073108135.jpg</bildskada>
<bildnr />
</skd>
<skd>
<metod>100</metod>
<ts>
<ts-nr>321</ts-nr>
<ts-typskada>f.a. sprutbetong - Läckage - Tak</ts-typskada>
<ts-kdel>6</ts-kdel>
<ts-kelem>665</ts-kelem>
<ts-mtrl>6</ts-mtrl>
<ts-typ>50</ts-typ>
<ts-orsak>129</ts-orsak>
<ts-aktivitet>45</ts-aktivitet>
<ts-enhet>kg</ts-enhet>
<ts-aktivitet-tx>Injektering</ts-aktivitet-tx>
<ts-mangd>5.0000000000</ts-mangd>
</ts>
<ovr>
<ovr-kdel />
<ovr-kdel-tx />
<ovr-kelem />
<ovr-kelem-tx />
<ovr-mtrl />
<ovr-mtrl-tx />
<ovr-typ />
<ovr-typ-tx />
<ovr-orsak />
<ovr-aktivitet />
<ovr-aktivitet-tx />
<ovr-enhet />
<ovr-mangd />
</ovr>
<kdel>6</kdel>
<kelem>665</kelem>
<mtrl>6</mtrl>
<typ>50</typ>
<orsak>129</orsak>
<skd-tx>Huvudbärverk / Tak ytförstärkning / Fiberarmerad sprutbetong / Läckage / Vatten</skd-tx>
<tk>2</tk>
<anm>3/s</anm>
<aktivitet>45</aktivitet>
<mangd>5</mangd>
<enhet>kg</enhet>
<sekt1>694</sekt1>
<sekt2>694</sekt2>
<lage>CT</lage>
<lage-tx>Kalk, järn,mangan utfälning droppar rikligt</lage-tx>
<bildskada />
<bildnr>4517</bildnr>
</skd>
<skd>
<metod>100</metod>
<ts>
<ts-nr>321</ts-nr>
<ts-typskada>f.a. sprutbetong - Läckage - Tak</ts-typskada>
<ts-kdel>6</ts-kdel>
<ts-kelem>665</ts-kelem>
<ts-mtrl>6</ts-mtrl>
<ts-typ>50</ts-typ>
<ts-orsak>129</ts-orsak>
<ts-aktivitet>45</ts-aktivitet>
<ts-enhet>kg</ts-enhet>
<ts-aktivitet-tx>Injektering</ts-aktivitet-tx>
<ts-mangd />
</ts>
<ovr>
<ovr-kdel />
<ovr-kdel-tx />
<ovr-kelem />
<ovr-kelem-tx />
<ovr-mtrl />
<ovr-mtrl-tx />
<ovr-typ />
<ovr-typ-tx />
<ovr-orsak />
<ovr-aktivitet />
<ovr-aktivitet-tx />
<ovr-enhet />
<ovr-mangd />
</ovr>
<kdel>6</kdel>
<kelem>665</kelem>
<mtrl>6</mtrl>
<typ>50</typ>
<orsak>129</orsak>
<skd-tx>Huvudbärverk / Tak ytförstärkning / Fiberarmerad sprutbetong / Läckage / Vatten</skd-tx>
<tk>1</tk>
<anm>Kalk, järn,mangan utfälning</anm>
<aktivitet>45</aktivitet>
<mangd />
<enhet>kg</enhet>
<sekt1>698</sekt1>
<sekt2 />
<lage>VT</lage>
<lage-tx>8/sek</lage-tx>
<bildskada />
<bildnr>4519-4520</bildnr>
</skd>
<skd>
<metod>100</metod>
<ts>
<ts-nr>513</ts-nr>
<ts-typskada>Lucka - Defekt - Takelement</ts-typskada>
<ts-kdel>15</ts-kdel>
<ts-kelem>1530</ts-kelem>
<ts-mtrl>13</ts-mtrl>
<ts-typ>48</ts-typ>
<ts-orsak>999</ts-orsak>
<ts-aktivitet>88</ts-aktivitet>
<ts-enhet>st</ts-enhet>
<ts-aktivitet-tx>Översyn</ts-aktivitet-tx>
<ts-mangd />
</ts>
<ovr>
<ovr-kdel />
<ovr-kdel-tx />
<ovr-kelem />
<ovr-kelem-tx />
<ovr-mtrl />
<ovr-mtrl-tx />
<ovr-typ />
<ovr-typ-tx />
<ovr-orsak />
<ovr-aktivitet />
<ovr-aktivitet-tx />
<ovr-enhet />
<ovr-mangd />
</ovr>
<kdel>15</kdel>
<kelem>1530</kelem>
<mtrl>13</mtrl>
<typ>48</typ>
<orsak>999</orsak>
<skd-tx>Gång/inspektionsbrygga etc / Lucka/dörr / Rostfritt stål / Defekt / Övrigt</skd-tx>
<tk>2</tk>
<anm>Går ej skruva saknas 2st skruvar</anm>
<aktivitet>88</aktivitet>
<mangd />
<enhet>st</enhet>
<sekt1>653</sekt1>
<sekt2 />
<lage>HT</lage>
<lage-tx>Nya skruvhål luckan som matchar</lage-tx>
<bildskada />
<bildnr>4523-4521</bildnr>
</skd>
<skd>
<metod>100</metod>
<ts>
<ts-nr>513</ts-nr>
<ts-typskada>Lucka - Defekt - Takelement</ts-typskada>
<ts-kdel>15</ts-kdel>
<ts-kelem>1530</ts-kelem>
<ts-mtrl>13</ts-mtrl>
<ts-typ>48</ts-typ>
<ts-orsak>999</ts-orsak>
<ts-aktivitet>88</ts-aktivitet>
<ts-enhet>st</ts-enhet>
<ts-aktivitet-tx>Översyn</ts-aktivitet-tx>
<ts-mangd>1.0000000000</ts-mangd>
</ts>
<ovr>
<ovr-kdel />
<ovr-kdel-tx />
<ovr-kelem />
<ovr-kelem-tx />
<ovr-mtrl />
<ovr-mtrl-tx />
<ovr-typ />
<ovr-typ-tx />
<ovr-orsak />
<ovr-aktivitet />
<ovr-aktivitet-tx />
<ovr-enhet />
<ovr-mangd />
</ovr>
<kdel>15</kdel>
<kelem>1530</kelem>
<mtrl>13</mtrl>
<typ>48</typ>
<orsak>999</orsak>
<skd-tx>Gång/inspektionsbrygga etc / Lucka/dörr / Rostfritt stål / Defekt / Övrigt</skd-tx>
<tk>2</tk>
<anm>Luckan behövs passas om</anm>
<aktivitet>88</aktivitet>
<mangd>1</mangd>
<enhet>st</enhet>
<sekt1>681</sekt1>
<sekt2 />
<lage>VT</lage>
<lage-tx>TV3 tidigare 2 skruv har sätts men mådet åtgärdas</lage-tx>
<bildskada />
<bildnr>4527</bildnr>
</skd>
<skd>
<metod>100</metod>
<ts>
<ts-nr>513</ts-nr>
<ts-typskada>Lucka - Defekt - Takelement</ts-typskada>
<ts-kdel>15</ts-kdel>
<ts-kelem>1530</ts-kelem>
<ts-mtrl>13</ts-mtrl>
<ts-typ>48</ts-typ>
<ts-orsak>999</ts-orsak>
<ts-aktivitet>88</ts-aktivitet>
<ts-enhet>st</ts-enhet>
<ts-aktivitet-tx>Översyn</ts-aktivitet-tx>
<ts-mangd>1.0000000000</ts-mangd>
</ts>
<ovr>
<ovr-kdel />
<ovr-kdel-tx />
<ovr-kelem />
<ovr-kelem-tx />
<ovr-mtrl />
<ovr-mtrl-tx />
<ovr-typ />
<ovr-typ-tx />
<ovr-orsak />
<ovr-aktivitet />
<ovr-aktivitet-tx />
<ovr-enhet />
<ovr-mangd />
</ovr>
<kdel>15</kdel>
<kelem>1530</kelem>
<mtrl>13</mtrl>
<typ>48</typ>
<orsak>999</orsak>
<skd-tx>Gång/inspektionsbrygga etc / Lucka/dörr / Rostfritt stål / Defekt / Övrigt</skd-tx>
<tk>3</tk>
<anm />
<aktivitet>88</aktivitet>
<mangd>1</mangd>
<enhet>st</enhet>
<sekt1>710</sekt1>
<sekt2 />
<lage>HT</lage>
<lage-tx>Nedre skruvhål passar inte</lage-tx>
<bildskada />
<bildnr>4543-4542</bildnr>
</skd>
</skdr>
<ritningar>212B2B01 212B2B02 212B2B03 212B2B04</ritningar>
<skd-antal>6</skd-antal>
<sekt-min>653</sekt-min>
<sekt-max>710</sekt-max>
<tk-min>1</tk-min>
<tk-max>3</tk-max>
<n0:meta xmlns:n0="http://openrosa.org/xforms">
<n0:instanceID>uuid:63c27738-df02-4298-9090-7ab96d4e1ab2</n0:instanceID>
<n0:instanceName>SöLä-25-212-2016-04-08-MFR RLS-4ae669a1-7d89-424a-bfab-26d506da0604</n0:instanceName>
</n0:meta>
At each 'skd' node I want to add the 'instanceID' attribute of the root element so that each 'skd' node will look something like:
<skdr>
<skd>
<id>uuid:63c27738-df02-4298-9090-7ab96d4e1ab2</id>
<metod>100</metod>
So I'm trying to use this XSL-file for the transformation, which is not working as intended:
xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<dataroot>
<xsl:apply-templates select="#*|node()"/>
</dataroot>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//skd">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
<ID><xsl-copy-of select="/SoLa_Tu_Insp_2016-03-13/#instanceID"/></ID>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
The result I get when using the above transformation is like this:
<?xml version="1.0" encoding="utf-8"?>
<dataroot>
<SoLa_Tu_Insp_2016-03-13 xmlns="http://opendatakit.org/submissions" id="SOLA-160313" instanceID="uuid:63c27738-df02-4298-9090-7ab96d4e1ab2" submissionDate="2016-04-08T02:11:47.600Z" isComplete="true" markedAsCompleteDate="2016-04-08T02:13:12.322Z">
<start>2016-04-08T23:47:50.615Z</start>
<end>2016-04-08T02:11:30.954Z</end>
<deviceid>353375050176865</deviceid>
<telnr/>
<insp>
<objekt>25</objekt>
<objdel>212</objdel>
<objdel-tx>Bronstunneln</objdel-tx>
<datum>2016-04-08</datum>
<sign>MFR RLS</sign>
<anm>8</anm>
</insp>
<skdr>
<skd>
<metod>100</metod>
<ts>
<ts-nr>523</ts-nr>
<ts-typskada>Lucka - Lös - Takelement</ts-typskada>
<ts-kdel>15</ts-kdel>
<ts-kelem>1530</ts-kelem>
<ts-mtrl>13</ts-mtrl>
<ts-typ>35</ts-typ>
<ts-orsak>999</ts-orsak>
<ts-aktivitet>87</ts-aktivitet>
<ts-enhet>st</ts-enhet>
<ts-aktivitet-tx>Åtdragning</ts-aktivitet-tx>
<ts-mangd>1.0000000000</ts-mangd>
</ts>
Thers is no 'instanceID' at each 'skd' node. I've tested the XPATHs at http://www.freeformatter.com/xpath-tester.html and it seems to be OK.
Anyone have any idea what I'm doing wrong here?

Your template does not match the skd element in the source XML document, because that element is in a namespace.
Try it this way instead:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:odk="http://opendatakit.org/submissions"
exclude-result-prefixes="odk">
<xsl:output indent="yes" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<dataroot>
<xsl:apply-templates select="#*|node()"/>
</dataroot>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="odk:skd">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<ID xmlns="http://opendatakit.org/submissions">
<xsl:value-of select="/odk:SoLa_Tu_Insp_2016-03-13/#instanceID"/>
</ID>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Additional notes:
Starting a match pattern with // is redundant;
xsl-copy-of is not a valid XSLT instruction;
Your version <xsl:apply-templates select="#*|node()"/> would have duplicated the child nodes.

Related

remove duplicate entry in xml in mysql

I have duplicate entry in my xml column in my sql table see material8 key.I remove one entry.I am trying below query its removing both.Is there any way i can remove only one entry.
Update mytable set xml = replace (xml, "<Book key=\"material8\" active=\"true\" displayOrder=\"5\" />", "") where id = 9 and type_key="mykey1";
<?xml version="1.0" encoding="UTF-8"?>
<Type key="test1" publicKey="test2" >
<UIProperties>
<label locale="en_US">My book</label>
</UIProperties>
<Books>
<Book key="material1" active="true" displayOrder="0" >
<UIProperties>
<label locale="en_US">My Books</label>
</UIProperties>
</Book>
<Book key="material2" />
<Book key="material3" active="true" displayOrder="3" >
<Pages>
<Page key="material4" active="true" displayOrder="0" />
<Page key="material5" active="true" displayOrder="1" />
</Pages>
</Book>
<Book key="material6" active="true" displayOrder="4" />
<Book key="material7" active="true" displayOrder="2" />
<Book key="material8" active="true" displayOrder="5" />
<Book key="material8" active="true" displayOrder="5" />
</Books>
<Attributes>
<Attribute key="desc" />
<Attribute key="date1" />
<Attribute key="date2" />
</Attributes>
</Type>
A simple solution is to replace 2 books to 1, instead of 1 to none:
UPDATE mytable
SET xml = REPLACE(xml, "<Book key=\"material8\" active=\"true\" displayOrder=\"5\" /><Book key=\"material8\" active=\"true\" displayOrder=\"5\" />", "<Book key=\"material8\" active=\"true\" displayOrder=\"5\" />")
WHERE id = 9
AND type_key="mykey1";

XML/XSLT nested loop of attributes to produce HTML table

I am trying to produce a HTML table from some XML I have got through a SQL query. The XML produced looks like the following:
<root>
<form attribute1="1" attribute2="1" />
<form attribute1="1" attribute2="2" />
<form attribute1="1" attribute2="3" />
<form attribute1="2" attribute2="1" />
<form attribute1="2" attribute2="2" />
<form attribute1="3" attribute2="1" />
</root>
The table I am trying to produce needs to have a header row for each unique attribute1 with rows underneath for each attribute2, something like this:
<attribute1="1" />
<attribute2="1" />
<attribute2="2" />
<attribute2="3" />
<attribute1="2" />
<attribute2="1" />
<attribute2="2" />
<attribute1="3" />
<attribute2="1" />
I don't have much experience using XML/XSLT but I am hoping it would be possible to do something like loop through the forms, create a header row for each unique attribute1 then create data rows associated to the unique attribute1 underneath.
If you can only use XSLT 1.0, try this XSLT for starters, which uses the Muenchian Grouping method
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="form" match="form" use="#attribute1" />
<xsl:template match="root">
<xsl:copy>
<!-- Get first "form" element that occurs in each group -->
<xsl:for-each select="form[generate-id() = generate-id(key('form',#attribute1)[1])]">
<group>
<header><xsl:value-of select="#attribute1" /></header>
<!-- Get the "form" elements that make up the group -->
<xsl:apply-templates select="key('form', #attribute1)" />
</group>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="form">
<row><xsl:value-of select="#attribute2" /></row>
</xsl:template>
</xsl:stylesheet>
And here's some XSLT that can create an HTML table. This one is slightly more advanced as it works out the maximum number of columns for a row, and uses that in creating colspan attributes for the shorter rows
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:key name="form" match="form" use="#attribute1" />
<xsl:variable name="maxCells">
<xsl:for-each select="/root/form[generate-id() = generate-id(key('form',#attribute1)[1])]">
<xsl:sort select="count(key('form', #attribute1))" order="descending" />
<xsl:if test="position() = 1">
<xsl:value-of select="count(key('form', #attribute1))" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="root">
<table border="1">
<!-- Get first "form" element that occurs in each group -->
<xsl:for-each select="form[generate-id() = generate-id(key('form',#attribute1)[1])]">
<tr>
<th colspan="{$maxCells}">
<xsl:value-of select="#attribute1" />
</th>
</tr>
<tr>
<!-- Get the "form" elements that make up the group -->
<xsl:apply-templates select="key('form', #attribute1)" />
</tr>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template match="form">
<td>
<xsl:if test="position() = last()">
<xsl:attribute name="colspan">
<xsl:value-of select="$maxCells - count(key('form', #attribute1)) + 1" />
</xsl:attribute>
</xsl:if>
<xsl:value-of select="#attribute2" />
</td>
</xsl:template>
</xsl:stylesheet>

Transforming XML to XSL with values on another location

I'm trying to convert my XML into an XSL.
I succeeded in making the first part, but now I'm stuck on the second part. I'm trying to obtain a value from a key where it is defined somewhere else.
Maybe its easier to just show u :
Incoming XML file:
<?xml version="1.0" encoding="utf-16"?>
<AXFRoot>
<MAObject type="default" mdclass="PROGRAM">
<GUID dmname="">201406121715517010024191178005056B93D790000004460B00000D0F000989</GUID>
<Meta name="VRT_ESSENCE_DURATION" format="string" frate="">355280</Meta>
<Meta name="VRT_ESSENCE_AUDIO_CHANNELS" format="string" frate="">4</Meta>
<Meta name="VRT_CLIP_ID" format="string" frate="" />
<StratumEx name="VRT_CONTENT">
<Group orderidx="0" id="0" lastchanged="00010101000000">
<Segment id="0" contentid="999e584a-7192-45ff-8570-af6587e2938f" begin="0" end="8600" />
<Segment id="1" contentid="23502d29-a0b4-48c5-a8b2-596a195e2768" begin="8640" end="19760" />
<Segment id="2" contentid="b246ffb6-a56f-4e4e-8bd9-5da3b9cd7351" begin="19800" end="34840" />
<Segment id="3" contentid="1643dde7-3c5d-4675-a52e-77d00b70309b" begin="49000" end="49000" />
<Segment id="4" contentid="5ce3968f-5324-4172-90f3-bd6d22f696a7" begin="54800" end="58480" />
</Group>
</StratumEx>
<StratumEx name="VRT_ITEMS">
<Group orderidx="0" id="0" lastchanged="00010101000000">
<Segment id="0" contentid="328626e6-c794-494d-939a-39f7aa2e5a85" begin="11120" end="49200" />
<Segment id="1" contentid="1effe83f-7076-418f-b86f-cbd6ac6ba7ba" begin="81200" end="86600" />
</Group>
</StratumEx>
<StratumEx name="VRT_RESTRICTION" />
</MAObject>
<MAObject type="default" mdclass="S_VRT_CONTENT">
<GUID dmname="">999e584a-7192-45ff-8570-af6587e2938f</GUID>
<Meta name="VRT_CONTENT_TXT" format="string" frate="">Frag1</Meta>
</MAObject>
<MAObject type="default" mdclass="S_VRT_CONTENT">
<GUID dmname="">23502d29-a0b4-48c5-a8b2-596a195e2768</GUID>
<Meta name="VRT_CONTENT_TXT" format="string" frate="">Frag2</Meta>
</MAObject>
<MAObject type="default" mdclass="S_VRT_CONTENT">
<GUID dmname="">b246ffb6-a56f-4e4e-8bd9-5da3b9cd7351</GUID>
<Meta name="VRT_CONTENT_TXT" format="string" frate="">Frag3</Meta>
</MAObject>
<MAObject type="default" mdclass="S_VRT_CONTENT">
<GUID dmname="">1643dde7-3c5d-4675-a52e-77d00b70309b</GUID>
<Meta name="VRT_CONTENT_TXT" format="string" frate="">Frag4</Meta>
</MAObject>
<MAObject type="default" mdclass="S_VRT_CONTENT">
<GUID dmname="">5ce3968f-5324-4172-90f3-bd6d22f696a7</GUID>
<Meta name="VRT_CONTENT_TXT" format="string" frate="">Frag5</Meta>
</MAObject>
<MAObject type="default" mdclass="S_VRT_ITEMS">
<GUID dmname="">328626e6-c794-494d-939a-39f7aa2e5a85</GUID>
<Meta name="VRT_ITEMS_TXT" format="string" frate="">Frag6</Meta>
</MAObject>
<MAObject type="default" mdclass="S_VRT_ITEMS">
<GUID dmname="">1effe83f-7076-418f-b86f-cbd6ac6ba7ba</GUID>
<Meta name="VRT_ITEMS_TXT" format="string" frate="">Frag7</Meta>
</MAObject>
</AXFRoot>
Wanted result:
<MediaHAVEN_external_metadata version="1.0" name="VIAA">
<MDProperties>
<MEDIA_ID>201406121715517010024191178005056B93D790000004460B00000D0F000989</MEDIA_ID>
<VRT_ESSENCE_DURATION>355280</VRT_ESSENCE_DURATION>
<VRT_ESSENCE_AUDIO_CHANNELS>4</VRT_ESSENCE_AUDIO_CHANNELS>
<VRT_CLIP_ID></VRT_CLIP_ID>
</MDProperties>
<fragments>
<fragment>
<title>Frag1</title>
<original_start_z>0</original_start_z>
<original_end_z>8600</original_end_z>
</fragment>
<fragment>
<title>Frag2</title>
<original_start_z>8640</original_start_z>
<original_end_z>19760</original_end_z>
</fragment>
<fragment>
<title>Frag3</title>
<original_start_z>19800</original_start_z>
<original_end_z>34840</original_end_z>
</fragment>
<fragment>
<title>Frag4</title>
<original_start_z>49000</original_start_z>
<original_end_z>49000</original_end_z>
</fragment>
<fragment>
<title>Frag5</title>
<original_start_z>54800</original_start_z>
<original_end_z>58480</original_end_z>
</fragment>
<fragment>
<title>Frag6</title>
<original_start_z>11120</original_start_z>
<original_end_z>49200</original_end_z>
</fragment>
<fragment>
<title>Frag7</title>
<original_start_z>81200</original_start_z>
<original_end_z>86600</original_end_z>
</fragment>
</fragments>
</MediaHAVEN_external_metadata>
As you can see, those contentid's will do a lookup for the 'Frag' data. In my example: http://xsltransform.net/94hvTzt The 'Frag' data that you see right now, shouldn't belong there..
Could anyone point me in the correct direction?
Thanks!
Firstly, don't do this to create elements in XSLT...
<xsl:text disable-output-escaping="yes"><</xsl:text><xsl:value-of select="#name" /><xsl:text disable-output-escaping="yes">></xsl:text>
That way lies madness. If you want to create dynamically named elements, use the xsl:element command. You just need to do this....
<xsl:element name="{#name}">
<xsl:value-of select="."/>
</xsl:element>
But in answer to your question, to look up date from another location in your XML document, use an xsl:key
<xsl:key name="fragment" match="MAObject" use="GUID" />
To use this key, to look up the data, you would just do something like this (assuming you were positioned on a segment element)
<xsl:value-of select="key('fragment', #contentid)/Meta" />
Try this XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="fragment" match="MAObject" use="GUID" />
<xsl:template match="/">
<MediaHAVEN_external_metadata version="1.0" name="VIAA">
<MDProperties>
<MEDIA_ID><xsl:value-of select="AXFRoot/MAObject[StratumEx]/GUID" /></MEDIA_ID>
<xsl:for-each select="AXFRoot/MAObject[StratumEx]/Meta">
<xsl:element name="{#name}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</MDProperties>
<fragments>
<xsl:for-each select="AXFRoot/MAObject/StratumEx/Group/Segment">
<fragment>
<title><xsl:value-of select="key('fragment', #contentid)/Meta" /></title>
<original_start_z><xsl:value-of select="#begin" /></original_start_z>
<original_end_z><xsl:value-of select="#end" /></original_end_z>
</fragment>
</xsl:for-each>
</fragments>
</MediaHAVEN_external_metadata>
</xsl:template>
</xsl:stylesheet>
Or maybe this, to take a more template-based approach
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="fragment" match="MAObject" use="GUID" />
<xsl:template match="/">
<MediaHAVEN_external_metadata version="1.0" name="VIAA">
<xsl:apply-templates select="AXFRoot/MAObject[StratumEx]" />
</MediaHAVEN_external_metadata>
</xsl:template>
<xsl:template match="MAObject">
<MDProperties>
<MEDIA_ID><xsl:value-of select="GUID" /></MEDIA_ID>
<xsl:apply-templates select="Meta" />
</MDProperties>
<fragments>
<xsl:apply-templates select="StratumEx/Group/Segment" />
</fragments>
</xsl:template>
<xsl:template match="Meta">
<xsl:element name="{#name}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="Segment">
<fragment>
<title><xsl:value-of select="key('fragment', #contentid)/Meta" /></title>
<original_start_z><xsl:value-of select="#begin" /></original_start_z>
<original_end_z><xsl:value-of select="#end" /></original_end_z>
</fragment>
</xsl:template>
</xsl:stylesheet>

Extra empty table rows in XSLT html conversion and few other problems

I have few questions conserning XSLT to html conversion.
For some reason my xsl documents makes extra rows between every for-each loop. What can be the problem? Problem can be seen in html outputs.
Here's my xslt file
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="utf-8" media-type="text/html" />
<xsl:template match="/">
<html>
<head>
<title>KT-linjan moduulit</title>
</head>
<body>
<h1>KT-linja info</h1>
<table border="double">
<caption>Moduulit taulukoituna</caption>
<tr>
<th>identifier</th>
<th>nimi</th>
<th>kuvaus</th>
</tr>
<xsl:for-each select="production_line/unit/*">
<tr>
<td>
<xsl:value-of select="#modID" />
</td>
<td>
<xsl:value-of select="name" />
</td>
<td>
<xsl:value-of select="description" />
</td>
</tr>
</xsl:for-each>
</table>
<p>
<b>HUOM:</b>
</p>
<p>ID's of the modules are unique!</p>
<p>References between modules are correct!</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
and XML file:
<production_line>
<unit>
<lift_module modID="LM001">
<name>Päätynostin PN1</name>
<description lang="fi">Nostaa paletin alakuljettimelta ylös Starter-moduulille</description>
<conveyor type="BELT" level="down" feed="in">
<description lang="fi">Palettikuljetin (ala)</description>
<stopper />
</conveyor>
<conveyor type="BELT" level="up" feed="out">
<description lang="fi">Palettikuljetin (ylä)</description>
<stopper />
</conveyor>
<lift_shelf>
<conveyor feed="in_out" type="BAND">
<description lang="fi">Palettikuljetin (hissitaso)</description>
<stopper />
</conveyor>
<description lang="fi">Liikkuva hissitaso</description>
</lift_shelf>
<sensor type="INDUCTIVE">
<amount>2</amount>
</sensor>
<chassis type="SAFETY" width="500" heigth="1200" length="700">
<sensor type="OPTIC">
<amount>1</amount>
</sensor>
</chassis>
</lift_module>
<connection fromIDREF="LM001" toIDREF="SM001" />
</unit>
<unit>
<starter_module modID="SM001">
<name>Starter-moduuli ST1</name>
<description lang="fi">Jakaa paletit kolmelle kuljettimelle</description>
<conveyor type="BELT">
<description lang="fi">Palettikuljetin (keski)</description>
<stopper />
</conveyor>
<conveyor type="BELT">
<description lang="fi">Palettikuljetin (syöttö1)</description>
<stopper />
</conveyor>
<conveyor type="BELT">
<description lang="fi">Palettikuljetin (syöttö2)</description>
<stopper />
</conveyor>
<crossing />
<crossing />
<crossing />
<sensor type="INDUCTIVE">
<amount>3</amount>
</sensor>
<sensor type="OPTIC">
<amount>3</amount>
</sensor>
</starter_module>
<connection fromIDREF="SM001" toIDREF="WM001" />
</unit>
<unit>
<workstation modID="WM001">
<name>Työasema TA1</name>
<description lang="fi">Sisältää vasemman ja oikean työpisteen</description>
<conveyor type="BELT">
<description lang="fi">Palettikuljetin (keski)</description>
<stopper />
</conveyor>
<conveyor type="BELT">
<description lang="fi">Palettikuljetin (vasen)</description>
<stopper>stoppari</stopper>
</conveyor>
<conveyor type="BELT">
<description lang="fi">Palettikuljetin (oikea)</description>
<stopper />
</conveyor>
<crossing />
<crossing />
<crossing />
<sensor type="INDUCTIVE">
<amount>6</amount>
</sensor>
<sensor type="OPTIC">
<amount>6</amount>
</sensor>
<switch type="push_button" operate="manual">send-painike</switch>
<switch type="switch" operate="manual">pause-kytkin</switch>
</workstation>
<connection fromIDREF="WM001" toIDREF="LM002" />
</unit>
<unit>
<lift_module modID="LM002">
<name>Päätynostin PN2</name>
<description lang="fi">Laskee paletin ylhäältä alas paluukuljettimelle</description>
<conveyor type="BELT" level="down" feed="out">
<description lang="fi">Palettikuljetin (ala)</description>
<stopper />
</conveyor>
<conveyor type="BELT" level="up" feed="in">
<description lang="fi">Palettikuljetin (ylä)</description>
<stopper />
</conveyor>
<lift_shelf>
<description lang="fi">Liikkuva hissitaso</description>
<conveyor type="BELT" feed="in_out">
<description lang="fi">Palettikuljetin (hissitaso)</description>
<stopper />
</conveyor>
</lift_shelf>
<sensor type="INDUCTIVE">
<amount>2</amount>
</sensor>
<chassis type="SAFETY" width="500" heigth="1200" length="700">
<sensor type="OPTIC">
<amount>2</amount>
</sensor>
</chassis>
</lift_module>
</unit>
</production_line>
On left is my table and on the right table in correct format.
I need to check if every identifier has unique attribute name (modID, for example LM001) and post if its unique or not. How should this check be performed?
I also need to check if iDREF atributes in XML file are properly linked. For example in the end of first node there is and check that it is correctly linked to the next modID. Any idea about this one?
It also seems to add unnecessary row between "ID's of the modules are unique!" and "References between modules are correct!" lines (where should be posted the answers of the checks).
Don't do <xsl:for-each select="production_line/unit/*">. That is too unspecific, it also matches the <connection> elements (which generate the empty rows).
Do this instead: <xsl:for-each select="production_line/unit/lift_module">.
To check whether all modID values are uniqe, try to select a duplicate:
<xsl:variable name="duplicateModIds" select="
//*/#modID[
. = preceding::*/#modID
or
. = following::*/#modID
]
" />
<xsl:choose>
<xsl:when test="$duplicateModIds">
<p>IDs of the modules are NOT unique!</p>
<!-- probably output $duplicateModIds, too -->
</xsl:when>
<xsl:otherwise>
<p>IDs of the modules are unique.</p>
</xsl:otherwise>
</xsl:choose>
Note that this can also be solved more elegantly through an XSL key, but for now the "duct tape" solution should be fine. Think about using keys when the performance of your transformation starts to drop or your requirements become more complex.
To check whether all connections are correct, simply try to select an incorrect one:
<xsl:variable name="incorrectRefs" select="
//connection[
#fromIDREF != ../*/#modID
or (
../following-sibling::unit[1]
and #toIDREF != ../following-sibling::unit[1]/*/#modID
)
]
" />
<xsl:choose>
<xsl:when test="$incorrectRefs">
<p>References between modules are NOT correct!</p>
<!-- probably output $incorrectRefs, too -->
</xsl:when>
<xsl:otherwise>
<p>References between modules are correct.</p>
</xsl:otherwise>
</xsl:choose>
also need to check if iDREF atributes in XM

XSLT formatting HTML Input

I am looking to use an XSLT to strip attributes out of an HTML file. The HTML file looks like this:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<title>CB Comfy Bike</title>
<meta name="atg:string,index:$repositoryId" content="prod10005" />
<meta name="atg:date:creationDate" content="955050507" />
<meta name="atg:date:startDate" content="978325200" />
<meta name="atg:date:endDate" content="1009861200" />
<meta name="atg:string:$url"
content="atgrep:/ProductCatalog/frame-product/prod10005?locale=en_US" />
<meta name="atg:string,index:$baseUrl"
content="atgrep:/ProductCatalog/frame-product/prod10005" />
<meta name="atg:string:$repository.repositoryName" content="ProductCatalog" />
<meta name="atg:string:$itemDescriptor.itemDescriptorName" content="frame-product" />
<meta name="atg:string:childSKUs.$repositoryId" content="sku20007" />
<meta name="atg:string:childSKUs.$itemDescriptor.itemDescriptorName" content="bike-sku" />
<meta name="atg:date:childSKUs.creationDate" content="955068027" />
<meta name="atg:float:childSKUs.listPrice" content="400.0" />
<meta name="atg:float:childSKUs.salePrice" content="300.0" />
<meta name="atg:boolean:childSKUs.onSale" content="false" />
<meta name="atg:string:parentCategory.$repositoryId" content="cat55551" />
<meta name="atg:date:parentCategory.creationDate" content="956950321" />
<meta name="atg:string,docset:ancestorCategories.$repositoryId" content="cat10002" />
<meta name="atg:string,docset:ancestorCategories.$repositoryId" content="cat10003" />
<meta name="atg:string,docset:ancestorCategories.$repositoryId" content="cat55551" />
</head>
<body>
<div class="atg:role:displayName" id="0"> CB Comfy Bike </div>
<div class="atg:role:longDescription" id="1"> This bike is just right, whether you are a
commuter or want to explore the fire roads. The plush front suspension will smooth out
the roughest bumps and the big disc brakes provide extra stopping power for those big
downhills. </div>
<div class="atg:role:keywords" id="2"> mountain_bike comfort_bike </div>
<div class="atg:role:childSKUs.displayName" id="3"> CB Comfy Bike Medium </div>
<div class="atg:role:childSKUs.listPrice" id="4"> 400.0 </div>
<div class="atg:role:childSKUs.description" id="5"> Medium </div>
<div class="atg:role:parentCategory.displayName" id="6"> Mountain Bikes </div>
</body>
</html>
I am looking to at a new tag for each div, I have not focused on naming convensions yet, as it is proof of concept. However im not sure how to differenciate between div tags. This XSLT I have got so far is:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="head"/>
<xsl:template match="body">
<xsl:copy>
<xsl:value-of select="div/text()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Which returns:
<?xml version="1.0" encoding="utf-8"?>
<html>
<body> CB Comfy Bike </body>
</html>
How would i turn the input into something like this
<?xml version="1.0" encoding="UTF-8"?>
<root>
<tag1>CB Comfy Bike</tag1>
<tag2>This bike is just right, whether you are a
commuter or want to explore the fire roads. The plush front suspension will smooth out
the roughest bumps and the big disc brakes provide extra stopping power for those big
downhills.</tag2>
<tag3>mountain_bike comfort_bike</tag3>
<tag4>CB Comfy Bike Medium</tag4>
<tag5>400.0</tag5>
<tag6>Medium</tag6>
<tag7>Mountain Bikes</tag7>
</root>
The trouble i have is differentiating between the Div tags.
This short and simple transformation:
<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="/*">
<root>
<xsl:apply-templates select="body/div"/>
</root>
</xsl:template>
<xsl:template match="div">
<xsl:element name="tag{position()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<title>CB Comfy Bike</title>
<meta name="atg:string,index:$repositoryId" content="prod10005" />
<meta name="atg:date:creationDate" content="955050507" />
<meta name="atg:date:startDate" content="978325200" />
<meta name="atg:date:endDate" content="1009861200" />
<meta name="atg:string:$url"
content="atgrep:/ProductCatalog/frame-product/prod10005?locale=en_US" />
<meta name="atg:string,index:$baseUrl"
content="atgrep:/ProductCatalog/frame-product/prod10005" />
<meta name="atg:string:$repository.repositoryName" content="ProductCatalog" />
<meta name="atg:string:$itemDescriptor.itemDescriptorName" content="frame-product" />
<meta name="atg:string:childSKUs.$repositoryId" content="sku20007" />
<meta name="atg:string:childSKUs.$itemDescriptor.itemDescriptorName" content="bike-sku" />
<meta name="atg:date:childSKUs.creationDate" content="955068027" />
<meta name="atg:float:childSKUs.listPrice" content="400.0" />
<meta name="atg:float:childSKUs.salePrice" content="300.0" />
<meta name="atg:boolean:childSKUs.onSale" content="false" />
<meta name="atg:string:parentCategory.$repositoryId" content="cat55551" />
<meta name="atg:date:parentCategory.creationDate" content="956950321" />
<meta name="atg:string,docset:ancestorCategories.$repositoryId" content="cat10002" />
<meta name="atg:string,docset:ancestorCategories.$repositoryId" content="cat10003" />
<meta name="atg:string,docset:ancestorCategories.$repositoryId" content="cat55551" />
</head>
<body>
<div class="atg:role:displayName" id="0"> CB Comfy Bike </div>
<div class="atg:role:longDescription" id="1"> This bike is just right, whether you are a
commuter or want to explore the fire roads. The plush front suspension will smooth out
the roughest bumps and the big disc brakes provide extra stopping power for those big
downhills. </div>
<div class="atg:role:keywords" id="2"> mountain_bike comfort_bike </div>
<div class="atg:role:childSKUs.displayName" id="3"> CB Comfy Bike Medium </div>
<div class="atg:role:childSKUs.listPrice" id="4"> 400.0 </div>
<div class="atg:role:childSKUs.description" id="5"> Medium </div>
<div class="atg:role:parentCategory.displayName" id="6"> Mountain Bikes </div>
</body>
</html>
produces the wanted, correct result:
<root>
<tag1> CB Comfy Bike </tag1>
<tag2> This bike is just right, whether you are a
commuter or want to explore the fire roads. The plush front suspension will smooth out
the roughest bumps and the big disc brakes provide extra stopping power for those big
downhills. </tag2>
<tag3> mountain_bike comfort_bike </tag3>
<tag4> CB Comfy Bike Medium </tag4>
<tag5> 400.0 </tag5>
<tag6> Medium </tag6>
<tag7> Mountain Bikes </tag7>
</root>
Explanation:
Appropriate use of templates.
Use of the position() function.
Use of AVT (Attribute Value Templates).
Almost desired output )
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="head"/>
<xsl:template match="body">
<xsl:for-each select="div">
<xsl:element name="{concat('tag', position())}">
<xsl:value-of select="./text()"/>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I'd do something similar to Timur but I wouldn't use the for-each. I'd use a template to iterate over the div's within the body
Applying the following to the supplied XML
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="html">
<xsl:apply-templates select="body"/>
</xsl:template>
<xsl:template match="body">
<root>
<xsl:apply-templates select="div"/>
</root>
</xsl:template>
<xsl:template match="div">
<xsl:element name="{concat('tag', position())}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
produces the desired output
<?xml version="1.0" encoding="UTF-8"?>
<root>
<tag1> CB Comfy Bike </tag1>
<tag2> This bike is just right, whether you are a
commuter or want to explore the fire roads. The plush front suspension will smooth out
the roughest bumps and the big disc brakes provide extra stopping power for those big
downhills. </tag2>
<tag3> mountain_bike comfort_bike </tag3>
<tag4> CB Comfy Bike Medium </tag4>
<tag5> 400.0 </tag5>
<tag6> Medium </tag6>
<tag7> Mountain Bikes </tag7>
</root>
Use of:
Identity transform
attribute value template
apply-templates to iterate over child nodes