這是我的 XML 檔案:
<root>
<headers>
<header value="type1" />
<header value="type3" />
<header value="type2" />
</headers>
<data type1="data1_1" type2="data1_2" type3="data1_3" />
<data type1="data2_1" type2="data2_2" type3="data2_3" />
</root>
我想生成僅包含標題部分中列出的標題的 CSV。這是我的 xslt 檔案:
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" encoding="unicode" />
<xsl:template match="root">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="headers">
<xsl:apply-templates/><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="separator">
<xsl:text>	</xsl:text>
</xsl:template>
<!-- display first line header work ok -->
<xsl:template match="header">
<xsl:value-of select="@value" />
<xsl:if test="position() != last()">
<xsl:call-template name="separator" />
</xsl:if>
</xsl:template>
<xsl:key name="mykey" match="header" use="@value" />
<!-- For each data parameters check if exist in header and display with the good order ! NOT WORK -->
<xsl:template match="data">
<xsl:for-each select="@*">
<xsl:if test="key('mykey', name())">
<xsl:value-of select="." />
<xsl:if test="position() != last()">
<xsl:call-template name="separator" />
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我想要這種輸出格式(CSV):
type1 type3 type2
data1_1 data1_3 data1_2
data2_1 data2_3 data2_2
但我的輸出是(資料型別 2 不在正確的標題下):
type1 type3 type2
data1_1 data1_2 data1_3
data2_1 data2_2 data2_3
uj5u.com熱心網友回復:
我會做的簡單:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/root">
<xsl:variable name="headers" select="headers/header" />
<!-- header -->
<xsl:for-each select="$headers">
<xsl:value-of select="@value"/>
<xsl:if test="position()!=last()">
<xsl:text>	</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
<!-- data -->
<xsl:for-each select="data">
<xsl:variable name="data" select="." />
<xsl:for-each select="$headers">
<xsl:value-of select="$data/@*[name()=current()/@value]"/>
<xsl:if test="position()!=last()">
<xsl:text>	</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
或者(也許更有效),你可以這樣做:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name="data-value" match="data/@*" use="concat(name(), '|', generate-id(..))" />
<xsl:template match="/root">
<xsl:variable name="headers" select="headers/header" />
<!-- header -->
<xsl:for-each select="$headers">
<xsl:value-of select="@value"/>
<xsl:if test="position()!=last()">
<xsl:text>	</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
<!-- data -->
<xsl:for-each select="data">
<xsl:variable name="data-id" select="generate-id()" />
<xsl:for-each select="$headers">
<xsl:value-of select="key('data-value', concat(@value, '|', $data-id))"/>
<xsl:if test="position()!=last()">
<xsl:text>	</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
順便說一句,結果是一個制表符分隔的檔案,而不是 CSV。
uj5u.com熱心網友回復:
屬性沒有固定的順序。元素可以。因此,讓我們使用這些元素來提供您的訂購:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" encoding="unicode" />
<xsl:template match="Results">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="headers">
<xsl:apply-templates/><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="separator">
<xsl:text>	</xsl:text>
</xsl:template>
<!-- display first line header work ok -->
<xsl:template match="header">
<xsl:value-of select="@value" />
<xsl:if test="position() != last()">
<xsl:call-template name="separator" />
</xsl:if>
</xsl:template>
<!-- Use the order of the headers to choose the order of the attributes. -->
<xsl:template match="data">
<xsl:variable name="data" select="."/>
<xsl:for-each select="/root/headers/header">
<xsl:value-of select="$data/@*[name()=current()/@value]"/>
<xsl:if test="position() != last()">
<xsl:call-template name="separator" />
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
輸出:
type1
type3
type2
data1_1 data1_3 data1_2
data2_1 data2_3 data2_2
標題位于單獨的行上,因為我沒有更改您的代碼的那部分。
uj5u.com熱心網友回復:
- 為 text() 節點創建一個模板以消除元素之間的所有文本(新行、縮進)
- 明確地在行之間放置新行
這是您的 xslt,其中包含您想要的小修復:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" encoding="unicode" />
<xsl:template match="root">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="headers">
<xsl:apply-templates/><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="text()"></xsl:template>
<xsl:template name="separator">
<xsl:text> </xsl:text>
</xsl:template>
<!-- display first line header work ok -->
<xsl:template match="header">
<xsl:value-of select="@value" />
<xsl:if test="position() != last()">
<xsl:call-template name="separator" />
</xsl:if>
</xsl:template>
<xsl:key name="mykey" match="header" use="@value" />
<!-- For each data parameters check if exist in header and display with the good order ! NOT WORK -->
<xsl:template match="data">
<xsl:for-each select="@*">
<xsl:if test="key('mykey', name())">
<xsl:value-of select="." />
<xsl:choose>
<xsl:when test="position() != last()">
<xsl:call-template name="separator" />
</xsl:when>
<xsl:otherwise>
<xsl:text>
</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/471902.html
上一篇:XSL為行內容器結果創建fo表