I have a xml called paths.xml which can contain 1 to X number of filepaths to XMl-files that I need to merge into one for further processing.
I use the stylesheet below to do this, but now I need to group the data by a attribute in the outputted file in the same conversion. I have looked into muenchian grouping but cant figure out how to implement it in the same stylesheet that does the copying?
Each XML contains only tags for its group. The output I want to achieve is that each XML gets grouped under a new element with the groups attribute-name as its value.
Any ideas?
My stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" indent="yes" omit-xml-declaration="no" />
<xsl:template match="/">
<xsl:copy-of select="document(document('paths.xml')//file/path)/*/node()"/>
</xsl:template>
</xsl:stylesheet>
Example of XML before merge:
<?xml version="1.0" encoding="UTF-8"?>
<tags generator="xmlgenerator" id="123">
<tag group="group1">
<title lang="eng">title1</title>
</tag>
<tag group="group1">
<title lang="se">title2</title>
</tag>
<tag group="group1">
<title lang="eng">title3</title>
</tag>
</tags>
Wanted output:
<?xml version="1.0" encoding="UTF-8"?>
<tagcollection>
<group1>
<tag>
<title lang="rus">title1</title>
</tag>
<tag>
<title lang="se">title2</title>
</tag>
</group1>
<group2>
<tag>
<title lang="eng">title1</title>
</tag>
<tag>
<title lang="se">title2</title>
</tag>
</group2>
</tagcollection>
Change
<xsl:template match="/">
<xsl:copy-of select="document(document('paths.xml')//file/path)/*/node()"/>
</xsl:template>
to
<xsl:template match="/">
<tagcollection>
<xsl:apply-templates select="document(document('paths.xml')//file/path)/*"/>
</tagcollection>
</xsl:template>
and then add the key for Muenchian grouping
<xsl:key name="group" match="tag" use="@group"/>
and the templates for grouping along the lines of
<xsl:template match="/*">
<xsl:apply-templates select="tag[generate-id() = generate-id(key('group', @group)[1])]" mode="group"/>
</xsl:template>
<xsl:template match="tag" mode="group">
<xsl:element name="{@group}">
<xsl:apply-templates select="key('group', @group)"/>
</xsl:element>
</xsl:template>
<xsl:template match="tag/@group"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
You haven't shown the exact structure and nesting of the input documents, the above assumes a structure like
<root>
<tag group="group1">
<title lang="eng">title1</title>
</tag>
<tag group="group1">
<title lang="se">title2</title>
</tag>
<tag group="group1">
<title lang="eng">title3</title>
</tag>
</root>
where actually the exact name of the root element does not matter.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments