I am not savvy with XML/XSLT at all. I'm just trying to learn enough to transform this XML file into something that my Access database can use. The XML data was output in an attribute format and Access only likes the element format. I have the basic transformations down, but I can't seem to elementize the nested data.
I would like the final result to be all elements. At the moment my XSLT script is trying to include the parental name attribute in the child element's name, but that may not be necessary. It'd be awesome if I could have the list elements numbered within their names. Such as "AuthorList1", "AuthorList2" or "Author1", "Author2".
Here's the kind of XML that I'm dealing with (abbreviated):
XML
<Result>
<DocSum>
<Id>25587056</Id>
<Item Name="PubDate" Type="Date">2015 Jan 13</Item>
<Item Name="EPubDate" Type="Date">2015 Jan 13</Item>
<Item Name="Source" Type="String">Invest Ophthalmol Vis Sci</Item>
<Item Name="AuthorList" Type="List">
<Item Name="Author" Type="String">Wang Q</Item>
<Item Name="Author" Type="String">Tuten WS</Item>
<Item Name="Author" Type="String">Lujan BJ</Item>
</Item>
<Item Name="Title" Type="String">Adaptive optics microperimetry</Item>
<Item Name="Volume" Type="String">56</Item>
<Item Name="ArticleIds" Type="List">
<Item Name="pubmed" Type="String">25587056</Item>
<Item Name="pii" Type="String">iovs.14-15576</Item>
<Item Name="doi" Type="String">10.1167/iovs.14-15576</Item>
</Item>
<Item Name="References" Type="List"></Item>
<Item Name="HasAbstract" Type="Integer">1</Item>
</DocSum>
</Result
I've gotten pretty far with the XSLT, but I'm not all the way there. One issue that keeps cropping up is the empty elements (like References) get null names that are not allowed. That occurred when I attempted an command using a match pattern of "Item[@Type='List']". Also, I can't seem to get the child nodes (elements?) of the lists to become their own elements.
XSLT
<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="@*" >
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Item">
<xsl:element name="{@Name}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="child::Item">
<xsl:variable name="Parent" select="TEST"/>
<xsl:element name="{$Parent}{@Name}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
I hope that this made some sort of sense. I'm really not looking to become an expert in this since I doubt that I'll be dealing with XML transformations again for a real long time. I would appreciate ANY help that is forthcoming.
One issue you have is the template that matches
Item
By using
xsl:value-of
here, it will not carry on processing any child nodes, so you won't get any matching done on any childItem
elements. You need to usexsl:apply-templates
here, to allow templates to apply to the childrenAnother issue is with the other template that matches
child::Item
. I think this will also match the parentItem
elements too, so effectively has the same priority as the otherItem
template. You probably need to replace the match with this:Finally, you define the
Parent
variable in this template like so:This will set
Parent
to the value of the element namedTEST
, when perhaps you wanted just the literal value of "Test". So, you should define it like soTry this XSLT