在 XSLT 中处理同名的多个元素
Handling multiple elements with same name in XSLT
我有 xml 以下数据。
<Rows>
<Header>
<sourcetable>Table_1</sourcetable>
<targettable>Table_2</targettable>
</Header>
<Table>
<Source_Fieldname>DTIME_INSERTED</Source_Fieldname>
<Source_Type>Timestamp</Source_Type>
<Source_Fieldname>ID_JOB</Source_Fieldname>
<Source_Type>String</Source_Type>
</Table>
<Header>
<sourcetable>Table_3</sourcetable>
<targettable>Table_4</targettable>
</Header>
<Table>
<Source_Fieldname>DTIME_INSERTED</Source_Fieldname>
<Source_Type>Timestamp</Source_Type>
<Source_Fieldname>ID_JOB</Source_Fieldname>
<Source_Type>String</Source_Type>
</Table>
</Rows>
我正试图将其输出到每个 "Table" 元素的单独表格中,就像这样,但无法弄清楚,因为有多个元素具有相同的名称。
到目前为止,这就是我得到的。
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="Row">
<table border="1px" cellpadding="3" cellspacing="1" style='font-family:"Calibri"; font-size:12; font-weight:"normal"' >
<tr align="center">
<xsl:for-each select="preceding-sibling::Header[1]">
<th colspan="4" bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="sourcetable" /> </font>
</th>
<th colspan="4" bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="targettable" /> </font>
</th>
</xsl:for-each>
<th bgcolor="#FFCCBC" rowspan="2">Flagfield</th>
</tr>
<tr align="left">
<td bgcolor="#C5E1A5">Source_Fieldname</td>
<td bgcolor="#C5E1A5">Source_Type</td>
</tr>
<xsl:for-each select=".">
<tr>
<xsl:for-each select="Source_Fieldname">
<td> <xsl:value-of select="."/> </td>
</xsl:for-each>
<xsl:for-each select="Source_Type">
<td> <xsl:value-of select="."/> </td>
</xsl:for-each>
</tr>
</xsl:for-each>
</xsl:for-each>
</table>
<br /><br/>
</xsl:template>
</xsl:stylesheet>
如有任何关于如何实现所需输出的建议,我们将不胜感激。谢谢!
到目前为止,我设法创造了预期的结果,但是,我会认真地建议清理你的XML file/input,因为它使事情复杂化。
但是对于您当前的文件,您可以使用此 XSLT-1.0 样式表来获得所需的输出:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<!-- A template handling the main HTML stuff -->
<xsl:template match="/Rows">
<html>
<body>
<font size="2" face="Calibri" >
<h1>The following Source - Target Tables have DDL Mismatch(es)</h1>
<br />
<xsl:apply-templates select="Table" />
</font>
</body>
</html>
</xsl:template>
<xsl:template match="Table">
<table border="1px" cellpadding="3" cellspacing="1" style='font-family:"Calibri"; font-size:12; font-weight:"normal"' >
<tr align="center">
<xsl:for-each select="preceding-sibling::Header[1]">
<th colspan="1" bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="sourcetable" /> </font>
</th>
<th colspan="1" bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="targettable" /> </font>
</th>
</xsl:for-each>
<th bgcolor="#FFCCBC" rowspan="2">Flagfield</th>
</tr>
<tr align="left">
<td bgcolor="#C5E1A5">Source_Fieldname</td>
<td bgcolor="#C5E1A5">Source_Type</td>
</tr>
<xsl:for-each select="*[local-name()='Source_Fieldname']">
<tr>
<td><xsl:value-of select="."/></td>
<td><xsl:value-of select="following-sibling::Source_Type[1]"/></td>
</tr>
</xsl:for-each>
</table>
<br /><br/>
</xsl:template>
</xsl:stylesheet>
核心方面是 xsl:for-each
循环:
<xsl:for-each select="*[local-name()='Source_Fieldname']">
<tr>
<td><xsl:value-of select="."/></td>
<td><xsl:value-of select="following-sibling::Source_Type[1]"/></td>
</tr>
</xsl:for-each>
输出为:
它只是遍历所有名为 Source_Fieldname
的 <Table>
children,然后为这些 和 [=33= 创建一个 table 单元格] 对于第一个 following-sibling Source_Type
元素。这确实适用于双元素 table,但将其扩展到多个 children 情况应该没问题。
你有一个好的开始,但一些细节没有奏效。这是我的解决方法。
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
<html>
<head/>
<body>
<xsl:apply-templates select="Rows/Table"/>
</body>
</html>
</xsl:template>
<xsl:template match="Table">
<table border="1px" cellpadding="3" cellspacing="1" style='font-family:"Calibri"; font-size:12; font-weight:"normal"' >
<tr align="center">
<th bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="preceding-sibling::Header[1]/sourcetable" /> </font>
</th>
<th bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="preceding-sibling::Header[1]/targettable" /> </font>
</th>
</tr>
<tr align="left">
<td bgcolor="#C5E1A5">Source_Fieldname</td>
<td bgcolor="#C5E1A5">Source_Type</td>
</tr>
<xsl:apply-templates select="Source_Fieldname"/>
</table>
<br/><br/>
</xsl:template>
<xsl:template match="Source_Fieldname">
<tr>
<td> <xsl:value-of select="."/> </td>
<td> <xsl:value-of select="following-sibling::Source_Type[1]"/> </td>
</tr>
</xsl:template>
</xsl:stylesheet>
你可以在这里测试它:https://xsltfiddle.liberty-development.net/bFWR5Ej/1
我有 xml 以下数据。
<Rows>
<Header>
<sourcetable>Table_1</sourcetable>
<targettable>Table_2</targettable>
</Header>
<Table>
<Source_Fieldname>DTIME_INSERTED</Source_Fieldname>
<Source_Type>Timestamp</Source_Type>
<Source_Fieldname>ID_JOB</Source_Fieldname>
<Source_Type>String</Source_Type>
</Table>
<Header>
<sourcetable>Table_3</sourcetable>
<targettable>Table_4</targettable>
</Header>
<Table>
<Source_Fieldname>DTIME_INSERTED</Source_Fieldname>
<Source_Type>Timestamp</Source_Type>
<Source_Fieldname>ID_JOB</Source_Fieldname>
<Source_Type>String</Source_Type>
</Table>
</Rows>
我正试图将其输出到每个 "Table" 元素的单独表格中,就像这样,但无法弄清楚,因为有多个元素具有相同的名称。
到目前为止,这就是我得到的。
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="Row">
<table border="1px" cellpadding="3" cellspacing="1" style='font-family:"Calibri"; font-size:12; font-weight:"normal"' >
<tr align="center">
<xsl:for-each select="preceding-sibling::Header[1]">
<th colspan="4" bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="sourcetable" /> </font>
</th>
<th colspan="4" bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="targettable" /> </font>
</th>
</xsl:for-each>
<th bgcolor="#FFCCBC" rowspan="2">Flagfield</th>
</tr>
<tr align="left">
<td bgcolor="#C5E1A5">Source_Fieldname</td>
<td bgcolor="#C5E1A5">Source_Type</td>
</tr>
<xsl:for-each select=".">
<tr>
<xsl:for-each select="Source_Fieldname">
<td> <xsl:value-of select="."/> </td>
</xsl:for-each>
<xsl:for-each select="Source_Type">
<td> <xsl:value-of select="."/> </td>
</xsl:for-each>
</tr>
</xsl:for-each>
</xsl:for-each>
</table>
<br /><br/>
</xsl:template>
</xsl:stylesheet>
如有任何关于如何实现所需输出的建议,我们将不胜感激。谢谢!
到目前为止,我设法创造了预期的结果,但是,我会认真地建议清理你的XML file/input,因为它使事情复杂化。
但是对于您当前的文件,您可以使用此 XSLT-1.0 样式表来获得所需的输出:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<!-- A template handling the main HTML stuff -->
<xsl:template match="/Rows">
<html>
<body>
<font size="2" face="Calibri" >
<h1>The following Source - Target Tables have DDL Mismatch(es)</h1>
<br />
<xsl:apply-templates select="Table" />
</font>
</body>
</html>
</xsl:template>
<xsl:template match="Table">
<table border="1px" cellpadding="3" cellspacing="1" style='font-family:"Calibri"; font-size:12; font-weight:"normal"' >
<tr align="center">
<xsl:for-each select="preceding-sibling::Header[1]">
<th colspan="1" bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="sourcetable" /> </font>
</th>
<th colspan="1" bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="targettable" /> </font>
</th>
</xsl:for-each>
<th bgcolor="#FFCCBC" rowspan="2">Flagfield</th>
</tr>
<tr align="left">
<td bgcolor="#C5E1A5">Source_Fieldname</td>
<td bgcolor="#C5E1A5">Source_Type</td>
</tr>
<xsl:for-each select="*[local-name()='Source_Fieldname']">
<tr>
<td><xsl:value-of select="."/></td>
<td><xsl:value-of select="following-sibling::Source_Type[1]"/></td>
</tr>
</xsl:for-each>
</table>
<br /><br/>
</xsl:template>
</xsl:stylesheet>
核心方面是 xsl:for-each
循环:
<xsl:for-each select="*[local-name()='Source_Fieldname']">
<tr>
<td><xsl:value-of select="."/></td>
<td><xsl:value-of select="following-sibling::Source_Type[1]"/></td>
</tr>
</xsl:for-each>
输出为:
它只是遍历所有名为 Source_Fieldname
的 <Table>
children,然后为这些 和 [=33= 创建一个 table 单元格] 对于第一个 following-sibling Source_Type
元素。这确实适用于双元素 table,但将其扩展到多个 children 情况应该没问题。
你有一个好的开始,但一些细节没有奏效。这是我的解决方法。
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
<html>
<head/>
<body>
<xsl:apply-templates select="Rows/Table"/>
</body>
</html>
</xsl:template>
<xsl:template match="Table">
<table border="1px" cellpadding="3" cellspacing="1" style='font-family:"Calibri"; font-size:12; font-weight:"normal"' >
<tr align="center">
<th bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="preceding-sibling::Header[1]/sourcetable" /> </font>
</th>
<th bgcolor="#ccffff">
<font size="2" face="Calibri" style="text-transform:uppercase"> <xsl:value-of select="preceding-sibling::Header[1]/targettable" /> </font>
</th>
</tr>
<tr align="left">
<td bgcolor="#C5E1A5">Source_Fieldname</td>
<td bgcolor="#C5E1A5">Source_Type</td>
</tr>
<xsl:apply-templates select="Source_Fieldname"/>
</table>
<br/><br/>
</xsl:template>
<xsl:template match="Source_Fieldname">
<tr>
<td> <xsl:value-of select="."/> </td>
<td> <xsl:value-of select="following-sibling::Source_Type[1]"/> </td>
</tr>
</xsl:template>
</xsl:stylesheet>
你可以在这里测试它:https://xsltfiddle.liberty-development.net/bFWR5Ej/1