我遇到了一个循环问题,需要小组的一些指示。我能够循环一个孩子,但在添加第二个孩子时遇到了麻烦。
这是我的XML:
<wd:Report_Entry>
<wd:Beneficiaries_-_All>
<wd:EMPLID>00025</wd:EMPLID>
<wd:Last>LastName</wd:Last>
<wd:First>FirstName</wd:First>
<wd:WID>key1234</wd:WID>
</wd:Beneficiaries_-_All>
<wd:Beneficiaries_-_All>
<wd:EMPLID>00025</wd:EMPLID>
<wd:Last>LastName</wd:Last>
<wd:First>First2</wd:First>
<wd:WID>key4567</wd:WID>
</wd:Beneficiaries_-_All>
<wd:Beneficiaries_-_People>
<wd:DOB>Birth1</wd:DOB>
<wd:ID>ID1</wd:ID>
<wd:WID>key1234</wd:WID>
</wd:Beneficiaries_-_People>
<wd:Beneficiaries_-_People>
<wd:DOB>Birth2</wd:DOB>
<wd:ID>ID2</wd:ID>
<wd:WID>key4567</wd:WID>
</wd:Beneficiaries_-_People>
</wd:Report_Entry>
我的XSLT在
之下<xsl:output method="text"/>
<xsl:variable name="linefeed" select="'
'"></xsl:variable>
<xsl:template match="/">
<xsl:for-each select="/wd:Report_Data/wd:Report_Entry">
<xsl:for-each select="wd:Beneficiaries_-_All">
<xsl:text>"</xsl:text>
<xsl:value-of select="wd:EMPLID"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:Last"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:First"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="$linefeed"/>
</xsl:for-each>
<xsl:for-each select="wd:Beneficiaries_-_People">
<xsl:value-of select="wd:DOB"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:ID"/>
<xsl:text>"</xsl:text>
</xsl:for-each>
<xsl:value-of select="$linefeed"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我想要的输出是这样的CSV:
“00025”, “名字”, “First1”, “Birth1”, “ID1”
“00025”, “姓氏”, “First2”, “Birth2”, “ID2”
“00026”,“LastName”,“First1”,“Birth1”,“ID1”(以这种方式继续)
但我得到的每个报告条目:
“00025”, “名字”, “First1”,“
“00025”, “姓氏”, “First2”,“
Birth1“,”ID1“Birth2”,“ID2”
我对此网站的研究表明<apply-templates>
比<for-each>
更受欢迎。当我尝试这种方法时,格式给我一个问题。谢谢小组!
答案 0 :(得分:1)
这是一个显示一些XSLT功能的解决方案:
wd
相对)(我使用了<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="http://some.namespace/wd"
>
<xsl:output method="text" />
<xsl:key name="kPeople" match="wd:Beneficiaries_-_People" use="wd:WID" />
<xsl:template match="/">
<xsl:apply-templates select="wd:Report_Data/wd:Report_Entry/wd:Beneficiaries_-_All" />
</xsl:template>
<xsl:template match="wd:Beneficiaries_-_All">
<xsl:apply-templates select="wd:EMPLID" mode="csv" />
<xsl:apply-templates select="wd:Last" mode="csv" />
<xsl:apply-templates select="wd:First" mode="csv" />
<xsl:apply-templates select="key('kPeople', wd:WID)/wd:DOB" mode="csv" />
<xsl:apply-templates select="key('kPeople', wd:WID)/wd:ID" mode="csv-nl" />
</xsl:template>
<xsl:template match="*" mode="csv">
<xsl:value-of select="concat('"', ., '",')" />
</xsl:template>
<xsl:template match="*" mode="csv-nl">
<xsl:value-of select="concat('"', ., '"
')" />
</xsl:template>
</xsl:stylesheet>
前缀的伪名称空间URI
"00025","LastName","FirstName","Birth1","ID1"
"00025","LastName","First2","Birth2","ID2"
对于您的样本数据,结果如下:
<wd:DOB>
陷阱:
<xsl:apply-templates select="wd:EMPLID" mode="csv" />
)不存在,则不起作用。对于统一输入,元素总是在那里,但有时是空的,一切都很好。如果元素可能丢失,则需要更改脚本。在这两种情况下:了解您的数据。
模板匹配是一把双刃剑。它非常适合输入驱动的转换。输入XML通过样式表中的模板进行映射,只需要很少的管道。
另一方面,CSV是一种严格的输出格式,以输入驱动的方式创建它需要输入同样严格。由于XML允许缺少元素,因此甚至可能没有可以转换为输出字段的元素。在这种情况下,命名模板和参数可以提供帮助:
而不是
<xsl:call-template name="csv">
<xsl:with-param name="val" value="wd:EMPLID" />
</xsl:call-template>
我们可以
<xsl:template name="csv">
<xsl:param name="val" />
<xsl:value-of select="concat('"', $val, '",')" />
</xsl:call-template>
和
"",
这样可以确保即使缺少元素,仍会打印空字段set(list1)
。
答案 1 :(得分:0)
如果我理解正确,你只需要一个变量就可以了:
<xsl:for-each select="/wd:Report_Data/wd:Report_Entry">
<xsl:for-each select="wd:Beneficiaries_-_All">
<xsl:text>"</xsl:text>
<xsl:value-of select="wd:EMPLID"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:Last"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:First"/>
<xsl:text>","</xsl:text>
<!-- new code starts here -->
<xsl:variable name="WID" select="wd:WID"/>
<xsl:value-of select="../wd:Beneficiaries_-_People[wd:WID = $WID]/wd:DOB"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="../wd:Beneficiaries_-_People[wd:WID = $WID]/wd:ID"/>
<xsl:text>"</xsl:text>
<!-- end new code -->
<xsl:value-of select="$linefeed"/>
</xsl:for-each>
</xsl:for-each>
希望这有帮助!