-1

我对 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 转换吗?非常感谢您的支持。

4

2 回答 2

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>
于 2013-09-21T08:25:54.280 回答
0

这可以看作是一个分组问题。您有顺序元素,但您希望按名称元素(或者更确切地说,我假设的句号之前的名称元素部分是这里的逻辑)对它们进行分组。在 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构造来简化分组。

于 2013-09-21T08:36:01.333 回答