XML 使用 XSLT 进行数据透视
XML pivot using XSLT
我收到的 XML 格式如下:
-
<Origin>
<PackageReferenceNumber>
<Code>0</Code>
<Value>QAST ROW PKG 01</Value>
</PackageReferenceNumber>
<PackageReferenceNumber>
<Code>33</Code>
<Value>12345</Value>
</PackageReferenceNumber>
</Origin>
我想格式化它:
<Origin>
<PackageReferenceNumber>
<Code1>0</Code1>
<Value1>QAST ROW PKG 01</Value1>
<Code2>33</Code2>
<Value2>12345</Value2>
</PackageReferenceNumber>
</Origin>
我正在使用 XSLT 转换 XML。下面是我目前用来转换 XML 的 XSLT 代码。我是 XML 和 XSLT 的新手。任何帮助将不胜感激。
<?xml version="1.0" encoding ="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:template match="/">
<xsl:variable name="var1_initial" select="."/>
<QuantumViewResponse>
<xsl:attribute name="xsi:noNamespaceSchemaLocation" namespace="http://www.w3.org/2001/XMLSchema-instance">file:///C:/Users/test.xsd</xsl:attribute>
<QuantumViewEvents>
<SubscriptionEvents>
<SubscriptionFile>
<Origin>
<xsl:for-each select="QuantumViewResponse/QuantumViewEvents/SubscriptionEvents/SubscriptionFile/Origin/PackageReferenceNumber">
<xsl:variable name="var3_current" select="."/>
<PackageReferenceNumber>
<Code>
<xsl:value-of select="floor(Code)"/>
</Code>
<Value>
<xsl:value-of select="Value"/>
</Value>
</PackageReferenceNumber>
</xsl:for-each>
<xsl:for-each select="QuantumViewResponse/QuantumViewEvents/SubscriptionEvents/SubscriptionFile/Origin">
<xsl:variable name="var4_current" select="."/>
<TrackingNumber>
<xsl:value-of select="TrackingNumber"/>
</TrackingNumber>
</xsl:for-each>
</Origin>
</SubscriptionFile>
</SubscriptionEvents>
</QuantumViewEvents>
</QuantumViewResponse>
</xsl:template>
我不确定您为什么要以这种方式更改格式。输入 XML 更容易使用!
不过,从您当前的 XSLT 外观来看,您似乎只显示了 XML 的一部分。在这种情况下,最好从身份模板开始
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
然后添加一个模板以匹配 Origin
,您在其中创建单个 PackageReferenceNumber
,然后 select 所有现有模板。
<xsl:template match="Origin">
<xsl:copy>
<PackageReferenceNumber>
<xsl:apply-templates select="PackageReferenceNumber" />
</PackageReferenceNumber>
</xsl:copy>
</xsl:template>
并且在匹配PackageReferenceNumber
的模板中你会得到当前的位置,然后在select它的所有子节点之后,你会使用这个位置来改变它们的名字:
<xsl:template match="PackageReferenceNumber">
<xsl:variable name="pos" select="position()" />
<xsl:for-each select="*">
<xsl:element name="{local-name()}{$pos}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:for-each>
</xsl:template>
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="Origin">
<xsl:copy>
<PackageReferenceNumber>
<xsl:apply-templates select="PackageReferenceNumber" />
</PackageReferenceNumber>
</xsl:copy>
</xsl:template>
<xsl:template match="PackageReferenceNumber">
<xsl:variable name="pos" select="position()" />
<xsl:for-each select="*">
<xsl:element name="{local-name()}{$pos}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
编辑:为了回应您的评论,一种首选的方法是将对包的引用作为属性。尝试用这个替换最后一个模板:
<xsl:template match="PackageReferenceNumber">
<xsl:variable name="pos" select="position()" />
<xsl:for-each select="*">
<xsl:copy>
<xsl:attribute name="ref" select="$pos" />
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:for-each>
</xsl:template>
这会产生以下输出
<Origin>
<PackageReferenceNumber>
<Code ref="1">0</Code>
<Value ref="1">QAST ROW PKG 01</Value>
<Code ref="2">33</Code>
<Value ref="2">12345</Value>
</PackageReferenceNumber>
</Origin>
我收到的 XML 格式如下: -
<Origin>
<PackageReferenceNumber>
<Code>0</Code>
<Value>QAST ROW PKG 01</Value>
</PackageReferenceNumber>
<PackageReferenceNumber>
<Code>33</Code>
<Value>12345</Value>
</PackageReferenceNumber>
</Origin>
我想格式化它:
<Origin>
<PackageReferenceNumber>
<Code1>0</Code1>
<Value1>QAST ROW PKG 01</Value1>
<Code2>33</Code2>
<Value2>12345</Value2>
</PackageReferenceNumber>
</Origin>
我正在使用 XSLT 转换 XML。下面是我目前用来转换 XML 的 XSLT 代码。我是 XML 和 XSLT 的新手。任何帮助将不胜感激。
<?xml version="1.0" encoding ="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:template match="/">
<xsl:variable name="var1_initial" select="."/>
<QuantumViewResponse>
<xsl:attribute name="xsi:noNamespaceSchemaLocation" namespace="http://www.w3.org/2001/XMLSchema-instance">file:///C:/Users/test.xsd</xsl:attribute>
<QuantumViewEvents>
<SubscriptionEvents>
<SubscriptionFile>
<Origin>
<xsl:for-each select="QuantumViewResponse/QuantumViewEvents/SubscriptionEvents/SubscriptionFile/Origin/PackageReferenceNumber">
<xsl:variable name="var3_current" select="."/>
<PackageReferenceNumber>
<Code>
<xsl:value-of select="floor(Code)"/>
</Code>
<Value>
<xsl:value-of select="Value"/>
</Value>
</PackageReferenceNumber>
</xsl:for-each>
<xsl:for-each select="QuantumViewResponse/QuantumViewEvents/SubscriptionEvents/SubscriptionFile/Origin">
<xsl:variable name="var4_current" select="."/>
<TrackingNumber>
<xsl:value-of select="TrackingNumber"/>
</TrackingNumber>
</xsl:for-each>
</Origin>
</SubscriptionFile>
</SubscriptionEvents>
</QuantumViewEvents>
</QuantumViewResponse>
</xsl:template>
我不确定您为什么要以这种方式更改格式。输入 XML 更容易使用!
不过,从您当前的 XSLT 外观来看,您似乎只显示了 XML 的一部分。在这种情况下,最好从身份模板开始
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
然后添加一个模板以匹配 Origin
,您在其中创建单个 PackageReferenceNumber
,然后 select 所有现有模板。
<xsl:template match="Origin">
<xsl:copy>
<PackageReferenceNumber>
<xsl:apply-templates select="PackageReferenceNumber" />
</PackageReferenceNumber>
</xsl:copy>
</xsl:template>
并且在匹配PackageReferenceNumber
的模板中你会得到当前的位置,然后在select它的所有子节点之后,你会使用这个位置来改变它们的名字:
<xsl:template match="PackageReferenceNumber">
<xsl:variable name="pos" select="position()" />
<xsl:for-each select="*">
<xsl:element name="{local-name()}{$pos}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:for-each>
</xsl:template>
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="Origin">
<xsl:copy>
<PackageReferenceNumber>
<xsl:apply-templates select="PackageReferenceNumber" />
</PackageReferenceNumber>
</xsl:copy>
</xsl:template>
<xsl:template match="PackageReferenceNumber">
<xsl:variable name="pos" select="position()" />
<xsl:for-each select="*">
<xsl:element name="{local-name()}{$pos}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
编辑:为了回应您的评论,一种首选的方法是将对包的引用作为属性。尝试用这个替换最后一个模板:
<xsl:template match="PackageReferenceNumber">
<xsl:variable name="pos" select="position()" />
<xsl:for-each select="*">
<xsl:copy>
<xsl:attribute name="ref" select="$pos" />
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:for-each>
</xsl:template>
这会产生以下输出
<Origin>
<PackageReferenceNumber>
<Code ref="1">0</Code>
<Value ref="1">QAST ROW PKG 01</Value>
<Code ref="2">33</Code>
<Value ref="2">12345</Value>
</PackageReferenceNumber>
</Origin>