不同的excel布局从xml转换而来

时间:2018-05-15 15:50:11

标签: xml excel xslt

我有一个问题是使用XML数据转换在不同的excel单元格上获取重复值。 我想在每个excel行上报告的xml数据是NAME的VALUE包含字符串TYPE LINK和VER。 我必须在所有数据之间区分数据的唯一方法是渐进式DATA-S01号码。 以下是转换wrong data后生成的错误输出,但简而言之,我预计此expected data

我的XML数据

   <FILE EXTNAME="TEST">

        <VAR NAME="DATA-S01-TYPE" VALUE="A" />
        <VAR NAME="DATA-S01-LINK" VALUE="123" />
        <VAR NAME="DATA-S01-VER" VALUE="RED" />
        <VAR NAME="DATA-S02-TYPE" VALUE="B" />  
        <VAR NAME="DATA-S02-LINK" VALUE="987" />
        <VAR NAME="DATA-S02-VER" VALUE="BLUE" />

    </FILE>

和我的xslt

<xsl:stylesheet version="1.0" xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:my-scripts" xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="separator" select="'&#x9;'"/>

<xsl:template match="/">
    <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
        xmlns:o="urn:schemas-microsoft-com:office:office"
        xmlns:x="urn:schemas-microsoft-com:office:excel"
        xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
        xmlns:html="http://www.w3.org/TR/REC-html40">
        <xsl:apply-templates/>
    </Workbook>
</xsl:template>

<xsl:template match="/*">
    <Worksheet>
        <xsl:attribute name="ss:Name">
            <xsl:value-of select="local-name(/*/*)"/>
        </xsl:attribute>

        <Table x:FullColumns="1" x:FullRows="1">
            <xsl:for-each select="//FILE">
                <Row>
                    <Cell>
                        <Data ss:Type="String">
                            <xsl:value-of select="@EXTNAME"/>

                        </Data>
                    </Cell>
                </Row>
                <xsl:for-each select="VAR[contains(@NAME, 'TYPE')]/@VALUE">
                    <Row>
                        <Cell>
                            <Data ss:Type="String">
                                <xsl:value-of select="."/>

                            </Data>
                        </Cell>

                        <xsl:for-each select="//VAR[contains(@NAME, 'VER')]/@VALUE">
                            <Cell>
                                <Data ss:Type="String">
                                    <xsl:value-of select="."/>

                                </Data>
                            </Cell>
                        </xsl:for-each>
                        <xsl:for-each select="//VAR[contains(@NAME, 'LINK')]/@VALUE">
                            <Cell>
                                <Data ss:Type="String">
                                    <xsl:value-of select="."/>

                                </Data>
                            </Cell>
                        </xsl:for-each>

                    </Row>

                </xsl:for-each>

            </xsl:for-each>
            <xsl:apply-templates/>
        </Table>
    </Worksheet>
</xsl:template>
</xsl:stylesheet>

知道我哪里错了吗?

1 个答案:

答案 0 :(得分:0)

问题出在这条线上......

<xsl:for-each select="//VAR[contains(@NAME, 'VER')]/@VALUE">

这将获得名称属性为“VER”的所有VAR元素,而您只需要具有相同前缀的元素。

所以,你可以定义一个像这样的变量

<xsl:variable name="prefix" select="substring-before(../@NAME, '-TYPE')" />

然后你的表达就变成了......

<xsl:for-each select="//VAR[@NAME = concat($prefix, '-VER')]/@VALUE">

或者,稍微更高效(如果您的XML中实际上有多个FILE元素,则可能更可靠...)

<xsl:for-each select="../following-sibling::VAR[@NAME = concat($prefix, '-VER')]/@VALUE">

事实上,如果您只为每种类型提供一个“VER”和“LINK”,我认为您不需要xsl:for-each

尝试使用此模板

<xsl:template match="/*">
    <Worksheet ss:Name="{local-name(/*/*)}">
        <Table x:FullColumns="1" x:FullRows="1">
            <xsl:for-each select="//FILE">
                <Row>
                    <Cell>
                        <Data ss:Type="String">
                            <xsl:value-of select="@EXTNAME"/>
                        </Data>
                    </Cell>
                </Row>
                <xsl:for-each select="VAR[contains(@NAME, 'TYPE')]/@VALUE">
                    <Row>
                        <Cell>
                            <Data ss:Type="String">
                                <xsl:value-of select="."/>
                            </Data>
                        </Cell>
                        <xsl:variable name="prefix" select="substring-before(../@NAME, '-TYPE')" />
                        <Cell>
                            <Data ss:Type="String">
                                <xsl:value-of select="../following-sibling::VAR[@NAME = concat($prefix, '-VER')]/@VALUE"/>
                            </Data>
                        </Cell>
                        <Cell>
                            <Data ss:Type="String">
                                <xsl:value-of select="../following-sibling::VAR[@NAME = concat($prefix, '-LINK')]/@VALUE"/>
                            </Data>
                        </Cell>
                    </Row>
                </xsl:for-each>
            </xsl:for-each>
        </Table>
    </Worksheet>
</xsl:template>