我对XSLT没有多少经验。我需要你的帮助来为下面的xml准备正确的XSL转换。我有像
这样的XML<message>
<requisition>
<data-values>
<data-value multi-valued="false">
<name>Test_Grid-1.Name</name>
<value>1</value>
</data-value>
<data-value multi-valued="false">
<name>Test_Grid-1.SupportType</name>
<value>Monthly,Quarterly</value>
</data-value>
<data-value multi-valued="false">
<name>Test_Grid-1.Status</name>
<value>New</value>
</data-value>
<data-value multi-valued="false">
<name>Test_Grid-2.Name</name>
<value>2</value>
</data-value>
<data-value multi-valued="false">
<name>Test_Grid-2.SupportType</name>
<value>Monthly</value>
</data-value>
<data-value multi-valued="false">
<name>Test_Grid-2.Status</name>
<value>Existing</value>
</data-value>
</data-values>
</requisition>
<agent-parameter multi-valued="false">
<name>ActionType</name>
<value>New</value>
</agent-parameter>
<agent-parameter multi-valued="false">
<name>Dictionary</name>
<value>Test_Grid</value>
</agent-parameter>
<agent-parameter multi-valued="false">
<name>ActionName</name>
<value>SupportData</value>
</agent-parameter>
</message>
我想像这样准备XML:
<ext:message>
<ext:record>
<ext:name>SupportData</ext:name>
<ext:rowData>
<ext:rowAttribute name="Name">1</ext:rowAttribute>
<ext:rowAttribute name="SupportType">Monthly,Quarterly</ext:rowAttribute>
<ext:rowAttribute name="Status">New</ext:rowAttribute>
</ext:rowData>
</ext:record>
<ext:record>
<ext:name>SupportData</ext:name>
<ext:rowData>
<ext:rowAttribute name="Name">2</ext:rowAttribute>
<ext:rowAttribute name="SupportType">Monthly</ext:rowAttribute>
<ext:rowAttribute name="Status">Existing</ext:rowAttribute>
</ext:rowData>
</ext:record>
请你帮我解决XSL转换问题。非常感谢您的支持。
答案 0 :(得分:0)
像
这样的东西<xsl:for-each select="data-value[position() mod 3 = 1]">
<ext:Record>
<ext:name>...</ext:name>
<ext:rowData>
<ext:rowAttribute name="Name"><xsl:value-of select="substring(substring-after(name, 'Test-Grid_'), 1, 1)"/></ext:rowAttribute>
<ext:rowAttribute name="SupportType"><xsl:value-of select="following-sibling[1]/value"/></ext:rowAttribute>
<ext:rowAttribute name="Status"><xsl:value-of select="following-sibling[2]/value"/></ext:rowAttribute>
</ext:rowData>
</ext:Record>
</xsl:for-each>
答案 1 :(得分:0)
这可以被视为分组问题。你有顺序元素,但你希望通过 name 元素(或者更确切地说, name 元素的一部分)在完全停止之前对它们进行分组,我假设这是逻辑)。在XSLT 1.0中,您通常会使用一种名为Muenchian Grouping的技术来执行此操作。
首先,定义一个按相关名称“分组”数据值元素的键。
<xsl:key name="record" match="data-value" use="substring-before(name, '.')" />
因此,对于给定名称,例如“Test_Grid-2”,该键将包含记录中所需的所有元素。
要开始输出记录,您首先必须查看所有数据值元素,但只选择键中首先出现的给定“名称”元素。元素比较使用'generate-id()'方法完成,因此表达式如下所示:
<xsl:apply-templates
select="requisition/data-values/data-value
[generate-id() =
generate-id(key('record', substring-before(name, '.'))[1])]" mode="record" />
(这里的模式是因为最终的XSLT将有两个匹配数据值的模板,所以这将区分它们。)
然后,在匹配不同数据值元素的模板中,您将获得记录的所有元素,如此
<xsl:apply-templates select="key('record', substring-before(name, '.'))" />
有一点需要注意,您的预期输出是使用命名空间前缀'ext',但您没有显示前缀的声明。 (可能是因为你只是简化了你的例子),但实际上我希望输出像这样开始:
<ext:message xmlns:ext="http://mylovelynamespace.com">
无论如何,试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="ext">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="record" match="data-value" use="substring-before(name, '.')" />
<xsl:template match="message">
<ext:message>
<xsl:apply-templates select="requisition/data-values/data-value[generate-id() = generate-id(key('record', substring-before(name, '.'))[1])]" mode="record" />
</ext:message>
</xsl:template>
<xsl:template match="data-value" mode="record">
<ext:record>
<ext:name>SupportData</ext:name>
<xsl:apply-templates select="key('record', substring-before(name, '.'))" />
</ext:record>
</xsl:template>
<xsl:template match="data-value">
<ext:rowAttribute name="{substring-after(name, '.')}"><xsl:value-of select="value" /></ext:rowAttribute>
</xsl:template>
</xsl:stylesheet>
在XSLT 2.0中,您可以使用 xsl:for-each-group 结构来简化分组。