首页 > 解决方案 > 从xml转换的不同excel布局

问题描述

我在使用 XML 数据的转换获取不同 Excel 单元格上的重复值时遇到问题。我要在每个 excel 行上报告的 xml 数据是 NAME 的 VALUE,包含字符串 TYPE LINK 和 VER。我必须区分所有数据的唯一方法是渐进式 DATA-S01 编号。这是转换错误数据后生成的错误输出,但简而言之,我期望这个预期数据

我的 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>

知道我哪里错了吗?

标签: xmlexcelxslt

解决方案


问题出在这条线...

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

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

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

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

然后你的表情就变成了这样...

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

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

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

事实上,我认为你不需要xsl:for-each在这里,如果你只为每种类型设置一个“VER”和“LINK”。

试试这个模板

<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>

推荐阅读