XSLT: tips and tricks: how to generate node1, node2, …, nodeN

This time let me show you how to generate several similar XML elements like name1, name2, name3, …, nameN.

Input:

<?xml version="1.0" encoding="utf-8"?>
<names>
	<name>John Smith</name>
	<name>Bill Murray</name>
	<name>Anne Williams</name>
	<name>Henry Ford</name>
</names>

Expected output:

<?xml version="1.0" encoding="utf-8"?>
<root>
	<NAME1>John Smith</NAME1>
	<NAME2>Bill Murray</NAME2>
	<NAME3>Anne Williams</NAME3>
	<NAME4>Henry Ford</NAME4>
</root>

Almost always developers are trying to create XSLT like this:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
		<root>
			<xsl:if test="names/name[1]">
				<NAME1>
					<xsl:value-of select="names/name[1]"/>
				</NAME1>
			</xsl:if>
			<xsl:if test="names/name[2]">
				<NAME2>
					<xsl:value-of select="names/name[2]"/>
				</NAME2>
			</xsl:if>
			...
			<xsl:if test="names/name[N]">
				<NAMEN>
					<xsl:value-of select="names/name[N]"/>
				</NAMEN>
			</xsl:if>
		</root>
	</xsl:template>
</xsl:stylesheet>

But there is a short and elegant way:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
		<root>
			<xsl:for-each select="names/name">
				<xsl:element name="{concat('NAME', position())}">
					<xsl:value-of select="."/>
				</xsl:element>
			</xsl:for-each>
		</root>
    </xsl:template>
</xsl:stylesheet>

Gennady Kim

Building Specs/Designs/MRGs automatically (from XML data)

I’ve enhanced a little the XSLT described here. First version could build the structures only, and we decided to add DDF files (Gentran/GIS/SI model format) as the formats (X12, EDIFACT, IDocs, etc) libraries. Now we can get not only the structure, but also descriptions, data types, optional/mandatory and qualifiers with descriptions. These specs were built automatically, I added colored backgrounds only:

X12:
spec_x12
Continue reading

webMethods: how to create an XSD schema (2)

UPD (22 Oct 2014): The original createXSD doesn’t work properly in some cases, so now I’m using both createXSD and my XSLT

My previous post about XSL for converting NDF into XSD was a try to “reinvent a wheel”. There is a native way to do the same in WM – WmPublic/pub/schema/createXSD 🙂 I didn’t know about it, but now I do know. Sometimes I have to change generated XSDs but anyway I think it’s easier to use built-in methods. Well, lesson learned – ask an expert first 🙂

Gennady Kim

webMethods: how to create an XSD schema from NDF structure definition file(s)

One of our clients uses webMethods for EAI. I’m not a big expert in webMethods (WM), I know only my part – EAI, partners setup, testing and map development. WM uses it’s own way for the structures definition. I cannot use it in my work, I need standard XSD or at least DTD files. So I decided to find a way to somehow export or convert those NDF files into XSD. These NDF files are in XML format so I decided to develop an XSLT to transform them into XSD. Now I’d like to share it with you. Mention should be made that I’m not an WM expert – maybe this XSLT works for only these particular NDF files and won’t work for all the others, but if you have a similar task – just give it a try and please let me know if it works for you or not. Sometimes there are more than just one NDF file to describe the structure – my XSLT supports such cases (a variable “base” at the beginning is for the folder’s name). It might require some explanation. If you have problems with it – I could try to help, feel free to contact me (there is a contact form)

Continue reading

SAP IDoc FlatFile to XML converter

One of our projects is to create/change hundreds of maps and switch from SAP IDoc flat files to XML files. All of the test files are in the FlatFile format, so I decided to create a converter to translate them into XML. It’s clear that this task requires some kind of a library with the IDoc documents structures description (hierarchy, records, positions, etc). I decided to use IDoc DDFs (format used by IBM/Sterling Map Editor for creating structures – you can download them from GIS/SI or just use existing GIS/SI map) and XSLT for it, and several hours later can convert my test data from FF to XML in seconds:

Just an idea.

PS I don’t have access to SAP at the moment so I cannot use it for XML Idoc generation. Also, I have appropriate I/Os for existing IDocs so it made sense to convert these existing files.

PPS it’s clear that an XML->FF converter is easier to develop – you don’t need to care about the hierarchy.

Here is my XSLT code. It doesn’t work without appropriate DDF file so if you have no idea about XSL/DDF you won’t be able to use it. It’s for those who is experienced but lazy – just like me 🙂 Continue reading

Auxiliary XSLT for building specs/MRGs for XML

Here is a simple XSLT which helps me to “extract” the structure from XML file. I use it for building specifications/designs/MRGs in MS Excel format:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:variable name="default_indent" select="'& #x9;'" />
	<xsl:template match="/">
		<xsl:for-each select=".">
			<xsl:call-template name="processElement" />
		</xsl:for-each>
	</xsl:template>

	<xsl:template name="processElement">
		<xsl:param name="indent" select="''" />

		<xsl:value-of select="$indent"/>
		<xsl:value-of select="name()"/>
		<xsl:text>& #xA;</xsl:text>
		
		<xsl:for-each select="@*">
			<xsl:value-of select="concat($indent, $default_indent)"/>
			<xsl:value-of select="'@'"/>
			<xsl:value-of select="name()"/>
			<xsl:text>& #xA;</xsl:text>
		</xsl:for-each>

		<xsl:if test="count(./*) != 0">
			<xsl:for-each select="./*">
				<xsl:call-template name="processElement">
					<xsl:with-param name="indent">
						<xsl:value-of select="concat($indent, $default_indent)"/>
					</xsl:with-param>
				</xsl:call-template>
			</xsl:for-each>
		</xsl:if>
	</xsl:template>
</xsl:stylesheet>

Continue reading