我最近几周才开始接触xslt和xml,我迫切需要一些帮助来编写一些代码来实现我想要实现的目标。我有以下xml:
<?xml version="1.0" encoding="UTF-8"?>
<abc1 formName="Form">
<Level1>
<Element1>ZZZ</Element1>
<Element2>
<SubElement1>Apples</SubElement1>
<SubElement2>Oranges</SubElement2>
<SubElement3>Pears</SubElement3>
<SubElement4>Blueberries</SubElement4>
<SubElement5>Milkshakes</SubElement5>
</Element2>
</Level1>
<Level1>
<Element1>XXX</Element1>
<Element2>
<SubElement1>Apples</SubElement1>
<SubElement2>Oranges</SubElement2>
<SubElement3>Kiwifruit</SubElement3>
<SubElement4>Blueberries</SubElement4>
<SubElement5>Soda</SubElement5>
</Element2>
</Level1>
</abc1>
和下面的 html 表:
<table>
<tr>
<td width="180" > Row 1</td>
<td width="540" colspan="4"> Cell_A</td>
</tr>
<tr>
<td width="180" >Types</td>
<td width="180" >Type 1</td>
<td width="180" >Type 2</td>
<td width="180" >Type 3</td>
</tr>
<tr>
<td width="180" >Row 2</td>
<td width="180" >Cell_B</td>
<td width="180" >Cell_C</td>
<td width="180" >Cell_D</td>
</tr>
<tr>
<td width="180" > Row 3</td>
<td width="180" >Cell_E</td>
<td width="180" >Cell_F</td>
<td width="180" >Cell_G</td>
</tr>
<tr>
<td width="180" >Row 4</td>
<td width="180" >Cell_H</td>
<td width="180" >Cell_I</td>
<td width="180" >Cell_J</td>
</tr>
<tr>
<td width="180" > Row 5</td>
<td width="540" colspan="4"> Cell_K</td>
</tr>
</table>
我无法使用 xslt 将数据从 xml 提取到表中,因为我需要应用的规则使其非常复杂。以下是需要应用于我遇到问题的单元格的规则。
(1) 如果<Element1>
整个 xml 中的值相同,则:
如果<Element1>
= 'ZZZ' 那么 Cell_B = '10',Cell_C = '20',并且 Cell_D = '30'
如果<Element1>
= 'XXX',则 Cell_B = '100',Cell_C = '90',并且 Cell_D = '80'
但如果<Element1>
xml 中的值不同,则:
Cell_B = '10,100'、Cell_C = '20,90' 和 Cell_D = '30,80'
(2) 如果<SubElement5>
整个 xml 中的值相同,则:
Cell_J = 的值<SubElement5>
但如果<SubElement5>
xml 中的值不同,则:
Cell_J =<SubElement5>
以逗号分隔的两个值的值
所以在这种情况下,Cell_J 的值将是“奶昔,苏打水”。
我一直在尝试使用不同的东西:
<xsl:for-each select="./Level1/Element2">
<xsl:value-of select="./SubElement5"/>
</xsl:for-each>
但我无法确定我可以使用哪些代码来检查它们是否相同,因为我无法覆盖变量的值。
编辑:
请注意,我上面指出的单元格(单元格 b、c、d 和 j)是我唯一需要帮助的单元格。此外,Element1
我可以遇到四个潜在值:ZZZ、XXX、AAA 和 BBB。其中每个所需的值是:(单元格 b、c 和 d)
ZZZ:10,20,30
XXX:100,90,80
AAA:40,30,30
BBB:50,30,20
因此,如果整个 xml 中只有一个潜在值,则单元格应显示为上述值。如果两个元素 1 的值不同,则单元格应列出每个单元格中的上述值,用逗号分隔。
关于cell_j,我会试着解释得更好一点。
首先,我需要确定<SubElement5>
整个 xml 中的值是否相同。在这种情况下,它不是,在一个部分是奶昔,在另一个部分是“苏打水”。因此,cell_J 应包含文本“奶昔,苏打水”。
如果 xml 看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<abc1 formName="Form">
<Level1>
<Element1>ZZZ</Element1>
<Element2>
<SubElement1>Apples</SubElement1>
<SubElement2>Oranges</SubElement2>
<SubElement3>Pears</SubElement3>
<SubElement4>Blueberries</SubElement4>
<SubElement5>Milkshakes</SubElement5>
</Element2>
</Level1>
<Level1>
<Element1>XXX</Element1>
<Element2>
<SubElement1>Apples</SubElement1>
<SubElement2>Oranges</SubElement2>
<SubElement3>Kiwifruit</SubElement3>
<SubElement4>Blueberries</SubElement4>
<SubElement5>Milkshakes</SubElement5>
</Element2>
</Level1>
</abc1>
那么 cell_j 的值就是“奶昔”。
提前感谢任何可以提供帮助的人。
回答这个问题:
总结伍迪在下面所做的事情以供任何人将来参考:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/abc1">
<xsl:variable name="elements" select="//Element1[not(preceding::Element1 = .)]"/>
<table>
<tr>
<td width="180" > Row 1</td>
<td width="540" colspan="4"> Cell_A</td>
</tr>
<tr>
<td width="180" >Types</td>
<td width="180" >Type 1</td>
<td width="180" >Type 2</td>
<td width="180" >Type 3</td>
</tr>
<tr>
<td width="180" >Row 2</td>
<td width="180" > <xsl:for-each select="$elements">
<xsl:if test="position() != 1">,</xsl:if>
<xsl:choose>
<xsl:when test=". = 'AAA'">40</xsl:when>
<xsl:when test=". = 'BBB'">50</xsl:when>
<xsl:when test=". = 'XXX'">100</xsl:when>
<xsl:when test=". = 'ZZZ'">10</xsl:when>
</xsl:choose>
</xsl:for-each></td>
<td width="180" ><xsl:for-each select="$elements">
<xsl:if test="position() != 1">,</xsl:if>
<xsl:choose>
<xsl:when test=". = 'AAA'">30</xsl:when>
<xsl:when test=". = 'BBB'">30</xsl:when>
<xsl:when test=". = 'XXX'">90</xsl:when>
<xsl:when test=". = 'ZZZ'">20</xsl:when>
</xsl:choose>
</xsl:for-each></td>
<td width="180" ><xsl:for-each select="$elements">
<xsl:if test="position() != 1">,</xsl:if>
<xsl:choose>
<xsl:when test=". = 'AAA'">30</xsl:when>
<xsl:when test=". = 'BBB'">20</xsl:when>
<xsl:when test=". = 'XXX'">80</xsl:when>
<xsl:when test=". = 'ZZZ'">30</xsl:when>
</xsl:choose>
</xsl:for-each></td>
</tr>
<tr>
<td width="180" > Row 3</td>
<td width="180" >Cell_E</td>
<td width="180" >Cell_F</td>
<td width="180" >Cell_G</td>
</tr>
<tr>
<td width="180" >Row 4</td>
<td width="180" >Cell_H</td>
<td width="180" >Cell_I</td>
<td width="180" ><xsl:for-each select="//SubElement5[not(preceding::SubElement5/text() = text())]">
<xsl:if test="position() > 1">, </xsl:if>
<xsl:value-of select="."/>
</xsl:for-each></td>
</tr>
<tr>
<td width="180" > Row 5</td>
<td width="540" colspan="4"> Cell_K</td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
伍迪,再次感谢你。这太棒了。