XML映射普通数据序列到复杂数据数组

时间:2014-09-27 04:46:57

标签: arrays xml xslt position

可能这篇文章的标题不是最好的,但我真的不知道如何描述我想要实现的目标。

服务调用的响应是这样的xml结构:

<Document>
<kind>Data</kind>   
<rows>Chrome</rows>
<rows>Auckland</rows>
<rows>1</rows>
<rows>0</rows>
<rows>Firefox</rows>
<rows>Milan</rows>
<rows>1</rows>
<rows>0</rows>
<rows>Safari</rows>
<rows>Auckland</rows>
<rows>1</rows>
<rows>0</rows>
<rows>Safari</rows>
<rows>Milan</rows>
<rows>1</rows>
<rows>0</rows>
</Document>

(*未固定的行数)

我需要改变这样的事情:

<Document>   
<Row>
<Field_0>Chrome</Field_0>
<Field_1>Auckland</Field_1>
<Field_2>1</Field_2>
<Field_3>0</Field_3>
</Row>
<Row>
<Field_0>Firefox</Field_0>
<Field_1>Milan</Field_1>
<Field_2>1</Field_2>
<Field_3>0</Field_3>
</Row>
<Row>
<Field_0>Safari</Field_0>
<Field_1>Auckland</Field_1>
<Field_2>1</Field_2>
<Field_3>0</Field_3>
</Row>
<Row>
<Field_0>Safari</Field_0>
<Field_1>Milan</Field_1>
<Field_2>1</Field_2>
<Field_3>0</Field_3>
</Row>
</Document>

如你所见,有一个模式,目标结构是按位置而不是按名称构建的。 我使用的框架允许我使用XSLT(没有Java代码!)。

有没有人可以指出我正确的方向? 一个被查询的谷歌,但可能不知道如何描述我想要实现的目标,我找不到任何帮助。

谢谢Giovanni

2 个答案:

答案 0 :(得分:0)

在XSLT上对行进行迭代,存储在变量中创建字段名称所需的位置,形成包含字段的Row元素:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/Document">
    <Document>
        <xsl:for-each select="rows">
            <xsl:if test="position() mod 4 = 1">
            <xsl:variable name="pos" select="position()"/>
            <xsl:variable name="relativePos" select="($pos mod 4) - 1"/>
                <Row>
                    <xsl:element name="Field_{$relativePos}">
                        <xsl:value-of select="."/>
                    </xsl:element>
                    <xsl:element name="Field_{$relativePos + 1}">
                        <xsl:value-of select="../rows[$pos + 1]"/>
                    </xsl:element>
                    <xsl:element name="Field_{$relativePos + 2}">
                        <xsl:value-of select="../rows[$pos + 2]"/>
                    </xsl:element>
                    <xsl:element name="Field_{$relativePos + 3}">
                        <xsl:value-of select="../rows[$pos + 3]"/>
                    </xsl:element>
                </Row>
            </xsl:if>
        </xsl:for-each>
    </Document>
</xsl:template>
</xsl:stylesheet> 

答案 1 :(得分:0)

我会在文档级别做:

<apply-template select="rows[position() mod 4 = 1]" /> <!-- Selecting only rows 1, 5, 9... -->

并在行模板中:

<Row>
  <xsl:element name="Field_0">
    <xsl:value-of select="."/>
  </xsl:element>
  <xsl:element name="Field_1">
    <xsl:value-of select="following-sibling::rows[1]"/>
  </xsl:element>
  <xsl:element name="Field_2">
    <xsl:value-of select="following-sibling::rows[2]"/>
  </xsl:element>
  <xsl:element name="Field_3">
    <xsl:value-of select="following-sibling::rows[3]"/>
  </xsl:element>
</Row>

发布,因为我发现其他帖子对于这样一个简单的问题非常复杂。