Excluding XML empty nodes with XSLT -
i have simple xml. recreating xml , adding boilerplate text final xml file import indesign when i'm done.
here's problem: not xml fields being used in every record. so, when xslt adds boilerplate text appears in records don't include xml elements.
i tried using choose >> when >> otherwise element, use element if there, or ignore boilerplate , insert nothing if element not in record.
here sample xml data:
<?xml version="1.0" encoding="utf-8"?> <root> <story> <cl> <citydescription>city one</citydescription> <bk> <companyname>corporate name</companyname> <address>123 main st</address> <holdingco>company name</holdingco> <totalassets>128,319,000</totalassets> <totalliabilities>117,059,000</totalliabilities> <totaldeposits>89,847,000</totaldeposits> <equitycapital>11,260,000</equitycapital> </bk> <bk> <companyname>smaller company</companyname> <address>123 central st</address> </bk> </cl> <cl> <citydescription>city two</citydescription> <bk> <companyname>corporate name three</companyname> <address>123 high st</address> <holdingco>company name</holdingco> <totalassets>128,319,000</totalassets> <totalliabilities>117,059,000</totalliabilities> <totaldeposits>89,847,000</totaldeposits> <equitycapital>11,260,000</equitycapital> </bk> <bk> <companyname>smaller company four</companyname> <address>123 jones st</address> </bk> </cl> </story> </root> here xslt trying use, added "holding co:" , "total assets:" records did not contain elements:
<?xml version="1.0" encoding="utf-8"?><!-- dwxmlsource="testing.xml" --> <!doctype xsl:stylesheet [ ]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" /> <xsl:template match="/"> <root> <story> <xsl:for-each select="root/story/cl"> <citydescription><xsl:value-of select="citydescription"/></citydescription><xsl:text> </xsl:text> <xsl:for-each select="bk"> <companyname><xsl:value-of select="companyname"/></companyname><xsl:text> </xsl:text> <address><xsl:value-of select="address"/></address><xsl:text> </xsl:text> <holdingco><xsl:text>holding co: </xsl:text><xsl:value-of select="holdingco"/></holdingco><xsl:text> </xsl:text> <totalassets><xsl:text>total assets: </xsl:text><xsl:value-of select="totalassets"/></totalassets><xsl:text> </xsl:text> <totalliabilities><xsl:text>total liabilities: </xsl:text><xsl:value-of select="totalliabilities"/></totalliabilities><xsl:text> </xsl:text> <totaldeposits><xsl:text>total deposits: </xsl:text><xsl:value-of select="totaldeposits"/></totaldeposits><xsl:text> </xsl:text> <equitycapital><xsl:text>total assets: </xsl:text><xsl:value-of select="equitycapital"/></equitycapital><xsl:text> </xsl:text> </xsl:for-each> </xsl:for-each> </story> </root> </xsl:template> </xsl:stylesheet> i tried using choose >> when >> otherwise ignore elements , et al when not appear in data, output show nothing "otherwise" content.
any suggestions?
here's problem: not xml fields being used in every record. so, when xslt adds boilerplate text appears in records don't include xml elements. this templates -- not using templates in xslt not using classes in oo programming language.
this simple transformation (notice not single conditional instruction has been used):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output omit-xml-declaration="yes" indent="yes" /> <xsl:strip-space elements="*"/> <xsl:variable name="vnl" select="'
'"/> <xsl:template match="/"> <root> <story> <xsl:apply-templates select="root/story/cl"/> </story> </root> </xsl:template> <xsl:template match="cl"> <xsl:apply-templates select="citydescription"/> <xsl:apply-templates select="bk"/> </xsl:template> <xsl:template match="citydescription | companyname | address"> <xsl:element name="{name()}"> <xsl:value-of select="."/> </xsl:element> </xsl:template> <xsl:template match="bk"> <xsl:value-of select="$vnl"/> <xsl:apply-templates select="companyname"/> <xsl:apply-templates select="address"/> <xsl:apply-templates select="holdingco"/> <xsl:apply-templates select="totalassets"/> <xsl:apply-templates select="totalliabilities"/> <xsl:apply-templates select="totaldeposits"/> <xsl:apply-templates select="equitycapital"/> </xsl:template> <xsl:template match="holdingco"> <holdingco> <xsl:text>holding co: </xsl:text> <xsl:value-of select="."/> </holdingco> </xsl:template> <xsl:template match="totalassets"> <totalassets> <xsl:text>total assets: </xsl:text> <xsl:value-of select="."/> </totalassets> </xsl:template> <xsl:template match="totalliabilities"> <totalliabilities> <xsl:text>total liabilities: </xsl:text> <xsl:value-of select="."/> </totalliabilities> </xsl:template> <xsl:template match="totaldeposits"> <totaldeposits> <xsl:text>total deposits: </xsl:text> <xsl:value-of select="."/> </totaldeposits> </xsl:template> <xsl:template match="equitycapital"> <equitycapital> <xsl:text>total assets: </xsl:text> <xsl:value-of select="."/> </equitycapital> </xsl:template> <xsl:template match="text()"/> </xsl:stylesheet> when applied on provided xml document:
<root> <story> <cl> <citydescription>city one</citydescription> <bk> <companyname>corporate name</companyname> <address>123 main st</address> <holdingco>company name</holdingco> <totalassets>128,319,000</totalassets> <totalliabilities>117,059,000</totalliabilities> <totaldeposits>89,847,000</totaldeposits> <equitycapital>11,260,000</equitycapital> </bk> <bk> <companyname>smaller company</companyname> <address>123 central st</address> </bk> </cl> <cl> <citydescription>city two</citydescription> <bk> <companyname>corporate name three</companyname> <address>123 high st</address> <holdingco>company name</holdingco> <totalassets>128,319,000</totalassets> <totalliabilities>117,059,000</totalliabilities> <totaldeposits>89,847,000</totaldeposits> <equitycapital>11,260,000</equitycapital> </bk> <bk> <companyname>smaller company four</companyname> <address>123 jones st</address> </bk> </cl> </story> </root> produces wanted, correct result:
<root> <story> <citydescription>city one</citydescription> <companyname>corporate name</companyname> <address>123 main st</address> <holdingco>holding co: company name</holdingco> <totalassets>total assets: 128,319,000</totalassets> <totalliabilities>total liabilities: 117,059,000</totalliabilities> <totaldeposits>total deposits: 89,847,000</totaldeposits> <equitycapital>total assets: 11,260,000</equitycapital> <companyname>smaller company</companyname> <address>123 central st</address> <citydescription>city two</citydescription> <companyname>corporate name three</companyname> <address>123 high st</address> <holdingco>holding co: company name</holdingco> <totalassets>total assets: 128,319,000</totalassets> <totalliabilities>total liabilities: 117,059,000</totalliabilities> <totaldeposits>total deposits: 89,847,000</totaldeposits> <equitycapital>total assets: 11,260,000</equitycapital> <companyname>smaller company four</companyname> <address>123 jones st</address> </story> </root> as child elements of bk processed in document order, matching template can simplified just:
<xsl:template match="bk"> <xsl:value-of select="$vnl"/> <xsl:apply-templates/> </xsl:template> the same valid template matching cl -- can replaced by:
<xsl:template match="cl"> <xsl:apply-templates/> </xsl:template> finally, template can removed, because copies xslt built-in template matches element.
thus, transformation after these refactorings is:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output omit-xml-declaration="yes" indent="yes" /> <xsl:strip-space elements="*"/> <xsl:variable name="vnl" select="'
'"/> <xsl:template match="/"> <root> <story> <xsl:apply-templates select="root/story/cl"/> </story> </root> </xsl:template> <xsl:template match="citydescription | companyname | address"> <xsl:element name="{name()}"> <xsl:value-of select="."/> </xsl:element> </xsl:template> <xsl:template match="bk"> <xsl:value-of select="$vnl"/> <xsl:apply-templates/> </xsl:template> <xsl:template match="holdingco"> <holdingco> <xsl:text>holding co: </xsl:text> <xsl:value-of select="."/> </holdingco> </xsl:template> <xsl:template match="totalassets"> <totalassets> <xsl:text>total assets: </xsl:text> <xsl:value-of select="."/> </totalassets> </xsl:template> <xsl:template match="totalliabilities"> <totalliabilities> <xsl:text>total liabilities: </xsl:text> <xsl:value-of select="."/> </totalliabilities> </xsl:template> <xsl:template match="totaldeposits"> <totaldeposits> <xsl:text>total deposits: </xsl:text> <xsl:value-of select="."/> </totaldeposits> </xsl:template> <xsl:template match="equitycapital"> <equitycapital> <xsl:text>total assets: </xsl:text> <xsl:value-of select="."/> </equitycapital> </xsl:template> <xsl:template match="text()"/> </xsl:stylesheet> explanation:
the instruction:
<xsl:apply-templates select="somechildname"/> only applies templates (performs processing) if somechildname child node exists.
Comments
Post a Comment