使用XSLT的XML数据透视

时间:2015-10-12 14:53:04

标签: xml xslt pivot

我收到以下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>

1 个答案:

答案 0 :(得分:0)

我不确定您为什么要以这种方式更改格式。输入XML更容易使用!

但是,从您当前的XSLT看起来,您似乎只展示了XML的一部分。在这种情况下,最好从身份模板

开始
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
  </xsl:copy>
</xsl:template>  

然后添加模板以匹配您在其中创建单个Origin的{​​{1}},然后选择所有现有模板。

PackageReferenceNumber

在匹配<xsl:template match="Origin"> <xsl:copy> <PackageReferenceNumber> <xsl:apply-templates select="PackageReferenceNumber" /> </PackageReferenceNumber> </xsl:copy> </xsl:template> 的模板中,您将获得当前位置,然后在选择其所有子节点后,您将使用该位置更改其名称:

PackageReferenceNumber

试试这个XSLT

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