我有一个扁平的XML,如下所示:
<objectDataList>
<objectData>
<equipment>
<name>Chassis-One</name>
<type>Chassis</type>
</equipment>
</objectData>
<objectData>
<equipment>
<name>Shelf-One</name>
<type>Shelf</type>
</equipment>
</objectData>
<objectData>
<equipment>
<name>Shelf-Two</name>
<type>Shelf</type>
</equipment>
</objectData>
<objectData>
<equipment>
<name>Slot-One</name>
<type>Slot</type>
</equipment>
</objectData>
如何创建一个将我的XML转换为另一个XML的XSL:
<equipments>
<object>
<name>Chassis-One</name>
<object>
<name>Shelf-One</name>
<object>
<name>Slot-One</name>
</object>
</object>
</object>
就像在一个机箱中,有两个架子,而在一个架子里,有一个Slot -One ..
我尝试了一半,但我想不出如何使元素嵌套:
<xsl:template match="/response">
<equipments>
<object>
<xsl:apply-templates select="objectData"/>
</object>
</equipments>
<xsl:template match="objectData/equipment[type='Chassis']">
<name><xsl:value-of select="equipment/name"/></name>
<!-- Now I want to find the shelf according to the chassis name -->
<xsl:call-template name="find-shelf-according-to-chasis-name">
<xsl:with-param name="chassisName" select="equipment/name"/>
</xsl:call-template>
</xsl:template>
我希望有人可以解释一下
提前谢谢
答案 0 :(得分:0)
以下脚本将执行您想要的操作,由于机箱 - 机架 - 插槽结构必须在脚本中表示,因此它有点冗长。如果你的xml包含id和parent-id属性,那么脚本可能会更小,并且可以删除或放宽命名约定。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<equipments>
<xsl:apply-templates select="//equipment[type='Chassis']" />
</equipments>
</xsl:template>
<xsl:template match="equipment[type='Chassis']">
<xsl:variable name="suffix" select="substring-after(name, '-')" />
<object>
<xsl:copy-of select="name" />
<xsl:apply-templates select="//equipment[type='Shelf'][substring-after(name, '-')=$suffix]" />
</object>
</xsl:template>
<xsl:template match="equipment[type='Shelf']">
<xsl:variable name="suffix" select="substring-after(name, '-')" />
<object>
<xsl:copy-of select="name"/>
<xsl:apply-templates select="//equipment[type='Slot'][substring-after(name, '-')=$suffix]" />
</object>
</xsl:template>
<xsl:template match="equipment[type='Slot']">
<object>
<xsl:copy-of select="name"/>
</object>
</xsl:template>
</xsl:stylesheet>
您要求的部分使用substring-after
函数来确定名称后缀,并在后续选择中使用它。
答案 1 :(得分:0)
有一个相当简单(虽然有点冗长)的解决方案:
<xsl:template match="objectDataList">
<equipments>
<xsl:apply-templates select="objectData[equipment/type='Chassis']"/>
</equipments>
</xsl:template>
<xsl:template match="objectData[equipment/type='Chassis']">
<xsl:variable name="index" select="substring-after(equipment/name,'-')" />
<object>
<xsl:copy-of select="equipment/name" />
<xsl:apply-templates select="following-sibling::objectData[equipment/type='Shelf' and substring-after(equipment/name,'-') = $index]" />
</object>
</xsl:template>
<xsl:template match="objectData[equipment/type='Shelf']">
<xsl:variable name="index" select="substring-after(equipment/name,'-')" />
<object>
<xsl:copy-of select="equipment/name" />
<xsl:apply-templates select="following-sibling::objectData[equipment/type='Slot' and substring-after(equipment/name,'-') = $index]" />
</object>
</xsl:template>
<xsl:template match="objectData[equipment/type='Slot']">
<xsl:variable name="index" select="substring-after(equipment/name,'-')" />
<object>
<xsl:copy-of select="equipment/name" />
</object>
</xsl:template>
虽然有点重复,但最后三个模板几乎完全相同。但是,根据您的具体要求,它们可能会由不同的模板处理。
如果您可以保证货架始终跟随相关机箱等,那么您可以将第二个模板中的<xsl:apply-templates
更改为:
<xsl:apply-templates select="following-sibling::*[1]">
如果可能没有,那么你可以这样做:
<xsl:apply-templates select="following-sibling::*[1][equipment/type='Shelf']">