отличное преобразование макета Excel из XML - PullRequest
0 голосов
/ 15 мая 2018

У меня возникла проблема с получением повторного значения в другой ячейке Excel с использованием преобразования из данных XML.XML-данные, которые я хочу сообщить в каждой строке Excel, являются VALUE of NAME, содержит строку TYPE LINK и VER.Единственный способ различить данные между всеми - это прогрессивный номер DATA-S01.Вот неправильный вывод, сгенерированный после преобразования неверные данные , но вкратце я ожидал, что 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 голосов
/ 15 мая 2018

Проблема с этой строкой ...

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

Или чуть более эффективно (и, возможно, более надежно, если в вашем XML действительно было несколько элементов FILE) ...

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...