[英]How to transform this xml using xslt
我有以下格式的XML:
<?xml version="1.0" encoding="utf-8"?>
<dataset xmlns="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<metadata>
<item name="Col1" type="xs:string" length="14"/>
<item name="Col2" type="xs:string" length="92"/>
<item name="Col3" type="xs:string" length="66"/>
<item name="Col4 With Space" type="xs:string" length="32"/>
</metadata>
<data>
<row>
<value>SomeVal1</value>
<value>SomeVal2</value>
<value>SomeVal3</value>
<value>SomeVal4</value>
</row>
<row>
<value>SomeVal11</value>
<value>SomeVal22</value>
<value>SomeVal33</value>
<value>SomeVal44</value>
</row>
</data>
</dataset>
我想將其轉換為以下格式:
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<data>
<row>
<Col1 type="xs:string" length="14">SomeVal1</Col1>
<Col2 type="xs:string" length="92">SomeVal2</Col2>
<Col3 type="xs:string" length="66">SomeVal3</Col3>
<Col4_With_Space type="xs:string" length="32">SomeVal4</Col4_With_Space>
</row>
<row>
<Col1 type="xs:string" length="14">SomeVal11</Col1>
<Col2 type="xs:string" length="92">SomeVal22</Col2>
<Col3 type="xs:string" length="66">SomeVal33</Col3>
<Col4_With_Space type="xs:string" length="32">SomeVal44</Col4_With_Space>
</row>
</data>
</dataset>
我以前從來沒有使用過xslt,但我的能力不強。 我嘗試了類似的方法(不起作用),但被卡住了。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
<xsl:output encoding="UTF-8" indent="yes" method="xml" standalone="no" omit-xml-declaration="no"/>
<xsl:template match="dataset">
<xsl:for-each select="data/row">
<Col1 select="1"/>
<Col2 select="2"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
想要進行轉換的原因是SSIS“數據流”“ XML源”無法識別第一種格式。 我正在嘗試將數據從XML導入數據庫表。 “ XML Source”適用於第二種格式,但不適用於第一種格式。
我想我應該補充一點,不能保證XML元數據總是相同的,因此transform需要從元數據中獲取列名和類型,而不是硬編碼。
我以前從來沒有使用過xslt,但我的能力不強。
這當然不是適合初學者的任務。
正如我在對問題的評論中提到的那樣,您的第一個問題是源XML將其所有元素放在命名空間中。 您需要在樣式表中聲明相同的名稱空間,為其分配一個前綴,然后使用該前綴來尋址源XML中的元素。
嘗試的另一個問題是您實際上沒有從源XML獲取任何數據。
<Col1 select="1"/>
將為XML中的每一行輸出相同的靜態元素。
現在,真正的麻煩在於從metadata
部分獲取列名和屬性,並將它們與當前行中的相應單元格值配對。 這可以通過以下方式完成:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cog="http://developer.cognos.com/schemas/xmldata/1/"
exclude-result-prefixes="cog">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/cog:dataset">
<xsl:variable name="cols" select="cog:metadata/cog:item" />
<dataset>
<data>
<xsl:for-each select="cog:data/cog:row">
<xsl:variable name="curr-row-cells" select="cog:value" />
<row>
<xsl:for-each select="$cols">
<xsl:variable name="i" select="position()" />
<xsl:element name="{translate(@name, ' ', '_')}">
<xsl:copy-of select="@type | @length"/>
<xsl:value-of select="$curr-row-cells[$i]" />
</xsl:element>
</xsl:for-each>
</row>
</xsl:for-each>
</data>
</dataset>
</xsl:template>
</xsl:stylesheet>
結果
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<data>
<row>
<Col1 type="xs:string" length="14">SomeVal1</Col1>
<Col2 type="xs:string" length="92">SomeVal2</Col2>
<Col3 type="xs:string" length="66">SomeVal3</Col3>
<Col4_With_Space type="xs:string" length="32">SomeVal4</Col4_With_Space>
</row>
<row>
<Col1 type="xs:string" length="14">SomeVal11</Col1>
<Col2 type="xs:string" length="92">SomeVal22</Col2>
<Col3 type="xs:string" length="66">SomeVal33</Col3>
<Col4_With_Space type="xs:string" length="32">SomeVal44</Col4_With_Space>
</row>
</data>
</dataset>
提供的列名稱不一定是有效的XML元素名稱。 在此示例中, "Col4 With Space"
包含我已翻譯為下划線的空格-但是還有許多其他潛在的陷阱,這些陷阱可能導致名稱不可用並產生致命錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.