RE: [xsl] RE: Blank lines in transformed XML

Subject: RE: [xsl] RE: Blank lines in transformed XML
From: "Scott Trenda" <Scott.Trenda@xxxxxxxx>
Date: Wed, 7 Nov 2007 11:08:06 -0600
A few observations:
- Try removing
xmlns="http://xml.dod.mil/log/maint/fs/reportResponse/1.0.0"; from the
top of your stylesheet. I'm not sure where it's being used, but it just
begs for unexpected behavior.
- Where have you tried using <xsl:strip-space elements="*"/>? I don't
see it in your stylesheet below; try inserting it right below
<xsl:output/>.
- I've had some issues with whitespace before while using libxslt, but I
thought they went away as soon as I used <strip-space/>. If you'd like
to test that explicitly, try inserting this template at the bottom of
your stylesheet (it should handle any cases that <strip-space/>
doesn't):
  <xsl:template match="text()[not(normalize-space())]"/>

~ Scott


-----Original Message-----
From: Thomas Jackie R Ctr HQ 754 ELSG/LRM
[mailto:Jackie.Thomas.Ctr@xxxxxxxxxxxxx]
Sent: Wednesday, November 07, 2007 10:42 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: [xsl] RE: Blank lines in transformed XML

Let me give a specific example of the problem we are having at the
bottom of the original message.  We've tried using xsl:strip-space but
with no luck.

We are transforming xml being output by a program into xml to match our
xml schema.  We basically copy the original xml in the following way:
<xsl:template match="/"><xsl:apply-templates /></xsl:template> and/or
<xsl:template match="*"><xsl:copy><xsl:apply-templates
/></xsl:copy></xsl:template> and then we maniputlate the xml where
needed. In doing so we rename tags, manipulate tag contents and omit
tags altogether.  The way we are omitting tags is with a blank template
match.  For example <xsl:template match="title"/> is our way of omitting
any <title> tags from our transformed xml.  The problem is, the
transformed xml now has blank lines anywhere a <title> tag would have
appeared.

How do we remove the blank lines from the transformed xml.  We are using
xml/xslt 1.0 and the xerces parser.  Thanks for any help.

Here's a very simple example:
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="../fs/fs0ginxslt1.xslt" type="text/xsl" ?>
<gin elc="7494" remote_id="ACB" txn_dt_tm="07296/2002" program_id="GI"
version_date="101107" unit_id="A">
	<ReportTitle>A2010
- Actual Configuration</ReportTitle>
	<TypeOutput>2</TypeOutput>
	<ReportOptions>Current Operating Time (Including Engine
Parts)</ReportOptions>
	<EquipmentId>A2010</EquipmentId>
	<ActualConfiguration>
		<UnitId>A</UnitId>
		<EquipmentId>A2010</EquipmentId>
		<EquipmentDesignator>F015C</EquipmentDesignator>
		<OperatingTime>6706.8</OperatingTime>
		<ActualConfigurationRow>

<DetailDataRecordSequenceNumber>1</DetailDataRecordSequenceNumber>
			<UnitId>A</UnitId>
			<PartNumber>A2010</PartNumber>
			<LevelOfIndenture>01</LevelOfIndenture>

<CurrentOperatingTime>6706.8</CurrentOperatingTime>

<MaintenanceTypeInterval>H</MaintenanceTypeInterval>
			<TypeEquipment>M</TypeEquipment>
			<NextHigherAssemblyDataRow>
			</NextHigherAssemblyDataRow>
			<InstalledDateDataRow>
			</InstalledDateDataRow>

<PreviousOperatingTime>0.0</PreviousOperatingTime>
		</ActualConfigurationRow>
		<ActualConfigurationRow>

<DetailDataRecordSequenceNumber>2</DetailDataRecordSequenceNumber>
			<UnitId>A</UnitId>
			<PartNumber>E0584</PartNumber>
			<SerialNumber>PW0E680584</SerialNumber>
			<InstalledPosition>0002</InstalledPosition>
			<LevelOfIndenture>02</LevelOfIndenture>
			<WorkUnitCode>23Z00</WorkUnitCode>
			<WorkUnitCodeNarrative>TURBOFAN PWR
PLANT</WorkUnitCodeNarrative>
			<CurrentOperatingTime>N/A</CurrentOperatingTime>

<MaintenanceTypeInterval>7</MaintenanceTypeInterval>
			<TypeEquipment>E</TypeEquipment>
			<NextHigherAssemblyDataRow>
				<PartNumber>A2010</PartNumber>
				<TypeEquipment>M</TypeEquipment>
			</NextHigherAssemblyDataRow>
			<InstalledDateDataRow>
				<Date>2005237</Date>
			</InstalledDateDataRow>
		</ActualConfigurationRow>
	</ActualConfiguration>
</gin>

XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns="http://xml.dod.mil/log/maint/fs/reportResponse/1.0.0";>
	<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="no"/>
	<!-- Output Stylesheet Version 1.0.0 for Straightline
Transaction GIN created at Friday Aug 17 12:17:28 CDT 2007 -->

	<xsl:template match="/">
		<xsl:apply-templates/>
	</xsl:template>
	<xsl:template match="*">
		<xsl:copy>
			<xsl:apply-templates/>
		</xsl:copy>
	</xsl:template>
	<xsl:template match="gin">
		<IMDSCDB
xmlns="http://xml.dod.mil/log/maint/fs/reportResponse/1.0.0";>
			<CurrentOperatingTimeSummary>
				<ReportInformation>
					<ReportTitle>
						<xsl:value-of
select="ReportTitle"/>
					</ReportTitle>
					<xsl:if test="ReportOptions">
						<ReportOptions>
							<xsl:value-of
select="ReportOptions"/>
						</ReportOptions>
					</xsl:if>
					<ReportAsOfDate>
						<xsl:value-of
select="substring(@txn_dt_tm,1,5)"/>
						<xsl:text> </xsl:text>
						<xsl:value-of
select="substring(@txn_dt_tm,7,2)"/>:<xsl:value-of
select="substring(@txn_dt_tm,9,2)"/>:00</ReportAsOfDate>
					<CurrentEnterpriseLocationCode>
						<xsl:value-of
select="@elc"/>
					</CurrentEnterpriseLocationCode>
					<UnitId>
						<xsl:value-of
select="@unit_id"/>
					</UnitId>
				</ReportInformation>
				<xsl:apply-templates/>
			</CurrentOperatingTimeSummary>
		</IMDSCDB>
	</xsl:template>
	<xsl:template match="ReportTitle"/>
	<xsl:template match="TypeOutput"/>
	<xsl:template match="ReportOptions"/>
	<xsl:template match="TypeEquipment"/>
	<xsl:template match="ElapsedTime"/>
	<xsl:template match="ActualConfigurationRow">
		<ActualConfigurationData>
			<xsl:apply-templates/>
		</ActualConfigurationData>
	</xsl:template>
	<xsl:template match="ActualConfigurationRow/PartNumber">
		<xsl:choose>
			<xsl:when test="../TypeEquipment='P'">
				<PartNumber>
					<xsl:apply-templates/>
				</PartNumber>
			</xsl:when>
			<xsl:otherwise>
				<EquipmentId>
					<xsl:value-of select="."/>
				</EquipmentId>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<xsl:template match="ActualConfigurationRow/SerialNumber">
		<xsl:choose>
			<xsl:when test="../TypeEquipment='P'">
				<SerialNumber>
					<xsl:apply-templates/>
				</SerialNumber>
			</xsl:when>
			<xsl:when test="../TypeEquipment='E'">
				<ManufacturerCode>
					<xsl:value-of
select="substring(.,1,2)"/>
				</ManufacturerCode>
				<EngineSerialNumber>
					<xsl:value-of
select="substring(.,3,8)"/>
				</EngineSerialNumber>
			</xsl:when>
		</xsl:choose>
	</xsl:template>
	<xsl:template match="OperatingTime">
		<OperatingTime>
			<xsl:attribute name="decimalPosition">
				<xsl:choose>
					<xsl:when
test="contains(../OperatingTime,'.')">
						<xsl:value-of
select="string-length(substring-after(../OperatingTime, '.'))"/>
					</xsl:when>
					<xsl:otherwise>0</xsl:otherwise>
				</xsl:choose>
			</xsl:attribute>
			<xsl:choose>
				<xsl:when
test="contains(../OperatingTime,'.')">
					<xsl:value-of
select="normalize-space(substring-before(../OperatingTime,'.'))"/>
					<xsl:value-of
select="substring-after(../OperatingTime, '.')"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of
select="normalize-space(../OperatingTime)"/>
				</xsl:otherwise>
			</xsl:choose>
		</OperatingTime>
	</xsl:template>
	<xsl:template match="DifferentialCode">
		<DifferentiationCode>
			<xsl:value-of select="."/>
		</DifferentiationCode>
	</xsl:template>
	<xsl:template match="CageCode">
		<CommercialAndGovernmentEntityCode>
			<xsl:value-of select="."/>
		</CommercialAndGovernmentEntityCode>
	</xsl:template>
	<xsl:template match="CurrentOperatingTime">
		<xsl:if test=".!='N/A'">
			<OperatingTime>
				<xsl:attribute name="decimalPosition">
					<xsl:choose>
						<xsl:when
test="contains(../CurrentOperatingTime,'.')">
							<xsl:value-of
select="string-length(substring-after(../CurrentOperatingTime, '.'))"/>
						</xsl:when>

<xsl:otherwise>0</xsl:otherwise>
					</xsl:choose>
				</xsl:attribute>
				<xsl:choose>
					<xsl:when
test="contains(../CurrentOperatingTime,'.')">
						<xsl:value-of
select="normalize-space(substring-before(../CurrentOperatingTime,'.'))"/
>
						<xsl:value-of
select="substring-after(../CurrentOperatingTime, '.')"/>
					</xsl:when>
					<xsl:otherwise>
						<xsl:value-of
select="normalize-space(../CurrentOperatingTime)"/>
					</xsl:otherwise>
				</xsl:choose>
			</OperatingTime>
		</xsl:if>
	</xsl:template>
	<xsl:template match="NextHigherAssemblyDataRow">
		<xsl:if test="*">
			<NextHigherAssemblyData>
				<xsl:apply-templates/>
			</NextHigherAssemblyData>
		</xsl:if>
	</xsl:template>
	<xsl:template match="NextHigherAssemblyDataRow/PartNumber">
		<xsl:choose>
			<xsl:when test="../TypeEquipment='P'">
				<PartNumber>
					<xsl:apply-templates/>
				</PartNumber>
			</xsl:when>
			<xsl:otherwise>
				<EquipmentId>
					<xsl:value-of select="."/>
				</EquipmentId>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<xsl:template match="NextHigherAssemblyDataRow/SerialNumber">
		<xsl:choose>
			<xsl:when test="../TypeEquipment='P'">
				<SerialNumber>
					<xsl:apply-templates/>
				</SerialNumber>
			</xsl:when>
			<xsl:when test="../TypeEquipment='E'">
				<ManufacturerCode>
					<xsl:value-of
select="substring(.,1,2)"/>
				</ManufacturerCode>
				<EngineSerialNumber>
					<xsl:value-of
select="substring(.,3,8)"/>
				</EngineSerialNumber>
			</xsl:when>
		</xsl:choose>
	</xsl:template>
	<xsl:template match="InstalledDateDataRow">
		<xsl:if test="Date">
			<InstallDate>
				<xsl:attribute
name="dateFormat">CCYYDDD</xsl:attribute>
				<xsl:value-of select="Date"/>
			</InstallDate>
		</xsl:if>
		<xsl:if test="Time">
			<InstalledAtOperatingTime>
				<xsl:attribute name="decimalPosition">
					<xsl:choose>
						<xsl:when
test="contains(Time,'.')">
							<xsl:value-of
select="string-length(substring-after(Time, '.'))"/>
						</xsl:when>

<xsl:otherwise>0</xsl:otherwise>
					</xsl:choose>
				</xsl:attribute>
				<xsl:choose>
					<xsl:when
test="contains(Time,'.')">
						<xsl:value-of
select="normalize-space(substring-before(Time,'.'))"/>
						<xsl:value-of
select="substring-after(Time, '.')"/>
					</xsl:when>
					<xsl:otherwise>
						<xsl:value-of
select="normalize-space(Time)"/>
					</xsl:otherwise>
				</xsl:choose>
			</InstalledAtOperatingTime>
		</xsl:if>
	</xsl:template>
	<xsl:template match="PreviousOperatingTime">
		<PreviousOperatingTime>
			<xsl:attribute name="decimalPosition">
				<xsl:choose>
					<xsl:when
test="contains(../PreviousOperatingTime,'.')">
						<xsl:value-of
select="string-length(substring-after(../PreviousOperatingTime, '.'))"/>
					</xsl:when>
					<xsl:otherwise>0</xsl:otherwise>
				</xsl:choose>
			</xsl:attribute>
			<xsl:choose>
				<xsl:when
test="contains(../PreviousOperatingTime,'.')">
					<xsl:value-of
select="normalize-space(substring-before(../PreviousOperatingTime,'.'))"
/>
					<xsl:value-of
select="substring-after(../PreviousOperatingTime, '.')"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of
select="normalize-space(../PreviousOperatingTime)"/>
				</xsl:otherwise>
			</xsl:choose>
		</PreviousOperatingTime>
	</xsl:template>
</xsl:transform>


Output XML (notice all the blank lines):
<?xml version="1.0" encoding="UTF-8"?>
<IMDSCDB xmlns="http://xml.dod.mil/log/maint/fs/reportResponse/1.0.0";>
	<CurrentOperatingTimeSummary>
		<ReportInformation>
			<ReportTitle>A2010
- Actual Configuration</ReportTitle>
			<ReportOptions>Current Operating Time (Including
Engine Parts)</ReportOptions>
			<ReportAsOfDate>07296 20:02:00</ReportAsOfDate>

<CurrentEnterpriseLocationCode>7494</CurrentEnterpriseLocationCode>
			<UnitId>A</UnitId>
		</ReportInformation>



		<EquipmentId>A2010</EquipmentId>
		<ActualConfiguration>
			<UnitId>A</UnitId>
			<EquipmentId>A2010</EquipmentId>
			<EquipmentDesignator>F015C</EquipmentDesignator>
			<OperatingTime
decimalPosition="1">67068</OperatingTime>
			<ActualConfigurationData>

<DetailDataRecordSequenceNumber>1</DetailDataRecordSequenceNumber>
				<UnitId>A</UnitId>
				<EquipmentId>A2010</EquipmentId>
				<LevelOfIndenture>01</LevelOfIndenture>
				<OperatingTime
decimalPosition="1">67068</OperatingTime>

<MaintenanceTypeInterval>H</MaintenanceTypeInterval>



				<PreviousOperatingTime
decimalPosition="1">00</PreviousOperatingTime>
			</ActualConfigurationData>
			<ActualConfigurationData>

<DetailDataRecordSequenceNumber>2</DetailDataRecordSequenceNumber>
				<UnitId>A</UnitId>
				<EquipmentId>E0584</EquipmentId>
				<ManufacturerCode>PW</ManufacturerCode>

<EngineSerialNumber>0E680584</EngineSerialNumber>

<InstalledPosition>0002</InstalledPosition>
				<LevelOfIndenture>02</LevelOfIndenture>
				<WorkUnitCode>23Z00</WorkUnitCode>
				<WorkUnitCodeNarrative>TURBOFAN PWR
PLANT</WorkUnitCodeNarrative>


<MaintenanceTypeInterval>7</MaintenanceTypeInterval>

				<NextHigherAssemblyData>
					<EquipmentId>A2010</EquipmentId>
				</NextHigherAssemblyData>
				<InstallDate
dateFormat="CCYYDDD">2005237</InstallDate>
			</ActualConfigurationData>
	</CurrentOperatingTimeSummary>
</IMDSCDB>

Current Thread