XSL使用多嵌套循环将XML转换为未完全加载的表
谢谢你 ,现在我可以通过XSLT将xml转换为表,但是,当我再添加一个嵌套循环时,结果没有完全加载,我不确定出了什么问题 数据XMLXSL使用多嵌套循环将XML转换为未完全加载的表,xml,xslt,Xml,Xslt,谢谢你 ,现在我可以通过XSLT将xml转换为表,但是,当我再添加一个嵌套循环时,结果没有完全加载,我不确定出了什么问题 数据XML <Records> <Person id="756252" date="15-Oct-2014"> <Gender>Male</Gender> <NameDetails> <Name NameType="Primary Name">
<Records>
<Person id="756252" date="15-Oct-2014">
<Gender>Male</Gender>
<NameDetails>
<Name NameType="Primary Name">
<NameValue>
<FirstName>Ken</FirstName>
<Surname>Wu</Surname>
</NameValue>
</Name>
<Name NameType="AKA">
<NameValue>
<FirstName>Kenneth</FirstName>
<Surname>Wu</Surname>
</NameValue>
</Name>
<Name NameType="AKA2">
<NameValue>
<FirstName>CAN</FirstName>
<Surname>Wu</Surname>
</NameValue>
</Name>
</NameDetails>
<Descriptions>
<Description Description1="11" Description2="12" Description3="13"/>
<Description Description1="21" Description2="22" Description3="23"/>
<Description Description1="31" Description2="32" Description3="33"/>
</Descriptions>
<RoleDetail>
<Roles RoleType="Primary">
<OccTitle SinceDay="17" SinceMonth="Nov" SinceYear="2009" OccCat="6">Thai</OccTitle>
</Roles>
</RoleDetail>
<DateDetails>
<Date DateType="Date of Birth">
<DateValue Year="1990" />
<DateValue Year="1991" />
</Date>
<Date DateType="Date of Issue">
<DateValue Year="2000" />
<DateValue Year="2001" />
</Date>
</DateDetails>
</Person>
<Person id="253555" date="14-Oct-2014">
<Gender>Male</Gender>
<NameDetails>
<Name NameType="Primary Name">
<NameValue>
<FirstName>Peter</FirstName>
<Surname>Lai</Surname>
</NameValue>
</Name>
</NameDetails>
<Descriptions>
<Description Description1="11" Description2="12" Description3="13"/>
<Description Description1="21" Description2="22"/>
</Descriptions>
<Date DateType="Date of Birth">
<DateValue Year="1992" />
</Date>
</Person>
</Records>
现在的问题是,由于第二个人的RoleDetail缺失,最后两行没有显示出来
对于数据,下面的节点可能在XML数据文件中,也可能不在XML数据文件中,如果该节点不是在XML中,请将其保留为空,否则它也应为循环
<RoleDetail>
<Roles RoleType="Primary">
<OccTitle SinceDay="17" SinceMonth="Nov" SinceYear="2009" OccCat="6">Thai</OccTitle>
</Roles>
</RoleDetail>
泰国人
**它将有大约35个像这样的可选元素。。
非常感谢@michael.hor257k在回答前面的问题时已经指出:您实际得到的结果是一个由
循环构成的矩阵。如果至少有一个矩阵维度为空,则乘积将为空
所以,我们必须“欺骗”一点。基本思想如下:对于矩阵的每个维度,我们提供了一个选择表达式,选择维度元素(如果存在)以及一种虚拟条目(如果不存在单个维度条目)。在您的情况下,Person
适合于此,因为我们知道每个矩阵中该实体只出现一次。我们创建一个变量person
,作为对这个基本元素的引用
而不是写作
<xsl:for-each select="../../DateDetails/Date/DateValue">
编辑
正如@michael.hor257k(谢谢!)所建议的那样,如果找不到标题,则需要采取一些措施,避免意外输出$person
的文本节点。问题的原因是,标题名(
)的提取是唯一不包含任何进一步的节点名或属性名选择的提取。为了解决这个问题,我替换了声明
<xsl:variable name="occTitle" select="."/>
借
+1,做得很好。我打算发布一些非常类似的东西,除了使用默认节点集1作为“虚拟节点”。但我更喜欢你的方法。我认为您应该做一个更正:
。否则,该单元格将充满来自该用户所有文本节点的垃圾。@Marcus Rickert感谢您耐心的解释!太酷了!还有一个后续问题:)当我执行代码时,我在最后两行“OccTitle”列(11)中得到了“Male Peter Lai”。我试图调试,似乎是在第一次执行到Person[2]“它跳回”然后是“give me”Male Peter Lai“我不明白为什么会这样。现在我很困惑,可能是我没有完全理解您的代码……:(编辑后是否包含更正?
<xsl:for-each select="../../DateDetails/Date/DateValue">
<xsl:for-each select="$person/DateDetails/Date/DateValue|$person[not ($person/DateDetails/Date/DateValue)]">
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<html>
<head>
<title>Records</title>
</head>
<body>
<table border="1">
<tr>
<th>ID</th>
<th>Date</th>
<th>Gender</th>
<th>NameType</th>
<th>FirstName</th>
<th>SurName</th>
<th>Description1</th>
<th>Description2</th>
<th>Description3</th>
<th>RoleType</th>
<th>OccTitle</th>
<th>SinceDay</th>
<th>SinceMonth</th>
<th>DateType</th>
<th>Year</th>
</tr>
<xsl:for-each select="Records/Person">
<xsl:variable name="person" select="."/>
<xsl:for-each select="$person/NameDetails/Name">
<xsl:variable name="name" select="."/>
<xsl:for-each select="$person/DateDetails/Date/DateValue|$person[not ($person/DateDetails/Date/DateValue)]">
<xsl:variable name="dateval" select="."/>
<xsl:for-each select="$person/RoleDetail/Roles/OccTitle|$person[not ($person/RoleDetail/Roles/OccTitle)]">
<xsl:variable name="occTitle" select="self::OccTitle"/>
<xsl:for-each select="$person/Descriptions/Description|$person[not ($person/Descriptions/Description)]">
<tr>
<td>
<xsl:value-of select="normalize-space(../../@id)"/>
</td>
<td>
<xsl:value-of select="normalize-space(../../@date)"/>
</td>
<td>
<xsl:value-of select="normalize-space(../../Gender)"/>
</td>
<td>
<xsl:value-of select="normalize-space($name/@NameType)"/>
</td>
<td>
<xsl:value-of select="normalize-space($name/NameValue/FirstName)"/>
</td>
<td>
<xsl:value-of select="normalize-space($name/NameValue/Surname)"/>
</td>
<td>
<xsl:value-of select="normalize-space(@Description1)"/>
</td>
<td>
<xsl:value-of select="normalize-space(@Description2)"/>
</td>
<td>
<xsl:value-of select="normalize-space(@Description3)"/>
</td>
<td>
<xsl:value-of select="normalize-space($occTitle/../@RoleType)"/>
</td>
<td>
<xsl:value-of select="normalize-space($occTitle)"/>
</td>
<td>
<xsl:value-of select="normalize-space($occTitle/@SinceDay)"/>
</td>
<td>
<xsl:value-of select="normalize-space($occTitle/@SinceMonth)"/>
</td>
<td>
<xsl:value-of select="normalize-space($dateval/../@DateType)"/>
</td>
<td>
<xsl:value-of select="normalize-space($dateval/@Year)"/>
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<xsl:variable name="occTitle" select="."/>
<xsl:variable name="occTitle" select="self::OccTitle"/>