首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >转换xml的XSLT样式表

转换xml的XSLT样式表
EN

Stack Overflow用户
提问于 2012-05-12 04:25:35
回答 1查看 101关注 0票数 2

我正在尝试创建一个xslt样式表来转换xml。我曾研究过muenchian方法,但对它的工作原理并不熟悉。我遇到了一些困难,因为每个ManifestNo都可以有任意数量的SequenceNo,我正在尝试将源xml中的平面订单分组为目标xml中具有嵌套停止细节的订单。

代码语言:javascript
复制
<Orders>
  <Order>
    <ManifestNo>283749</ManifestNo>
    <Warehouse>35</Warehouse>
    <SequenceNo>1</SequenceNo>
    <CustomerOrderNo>3524771-01</CustomerOrderNo>
    <Weight>180</Weight>
  </Order>
  <Order>
    <ManifestNo>283749</ManifestNo>
    <Warehouse>35</Warehouse>
    <SequenceNo>1</SequenceNo>
    <CustomerOrderNo>3524771-02</CustomerOrderNo>
    <Weight>250</Weight>
  </Order>
  <Order>
    <ManifestNo>283749</ManifestNo>
    <Warehouse>35</Warehouse>
    <SequenceNo>2</SequenceNo>
    <CustomerOrderNo>3524728-01</CustomerOrderNo>
    <Weight>25</Weight>
    </Order>
  <Order>
    <ManifestNo>283750</ManifestNo>
    <Warehouse>50</Warehouse>
    <SequenceNo>1</SequenceNo>
    <CustomerOrderNo>5464565-01</CustomerOrderNo>
    <Weight>150</Weight>
  </Order>
  <Order>
    <ManifestNo>283750</ManifestNo>
    <Warehouse>50</Warehouse>
    <SequenceNo>2</SequenceNo>
    <CustomerOrderNo>5874565-02</CustomerOrderNo>
    <Weight>125</Weight>
  </Order>
  <Order>
    <ManifestNo>283750</ManifestNo>
    <Warehouse>50</Warehouse>
    <SequenceNo>2</SequenceNo>
    <CustomerOrderNo>3524888-01</CustomerOrderNo>
    <Weight>95</Weight>
  </Order>
</Orders>

代码语言:javascript
复制
<Orders>
     <Order>
        <ManifestNo>283749</ManifestNo>
        <Warehouse>35</Warehouse> 
        <Stop>
            <SequenceNo>1</SequenceNo>
            <Freight>
                <CustomerOrderNo>3524771-01</CustomerOrderNo>
                <Weight>180</Weight>
            </Freight>
            <Freight>
                <CustomerOrderNo>3524771-02</CustomerOrderNo>
                <Weight>250</Weight>
            </Freight>
        </Stop>
        <Stop>
            <SequenceNo>2</SequenceNo>
            <Freight>
                <CustomerOrderNo>3524728-01</CustomerOrderNo>
                <Weight>25</Weight>
            </Freight>
            <Freight>
                <CustomerOrderNo>3524771-02</CustomerOrderNo>
                <Weight>250</Weight>
            </Freight>
        </Stop>
         </Order>
        <Order>
        <ManifestNo>283750</ManifestNo>
        <Warehouse>50</Warehouse> 
        <Stop>
            <SequenceNo>1</SequenceNo>
            <Freight>
                <CustomerOrderNo>5464565-01</CustomerOrderNo>
                <Weight>150</Weight>
            </Freight>
        </Stop>
        <Stop>
            <SequenceNo>2</SequenceNo>
            <Freight>
                <CustomerOrderNo>5874565-02</CustomerOrderNo>
                <Weight>125</Weight>
            </Freight>
            <Freight>
                <CustomerOrderNo>3524888-0</CustomerOrderNo>
                <Weight>95</Weight>
            </Freight>
        </Stop>
         </Order>
    </Orders>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-12 11:05:36

I.这个XSLT1.0转换

代码语言:javascript
复制
    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

     <xsl:key name="kOrderByNum" match="Order"
      use="ManifestNo"/>

     <xsl:key name="kSeqInOrder" match="SequenceNo"
      use="concat(../ManifestNo, '+', .)"/>

     <xsl:key name="kSeqByOrderNo" match="SequenceNo"
      use="../ManifestNo"/>

     <xsl:template match="Order"/>
     <xsl:template match="SequenceNo"/>

   <xsl:template match="/*">
     <Orders>
      <xsl:apply-templates/>
     </Orders>
     </xsl:template>

     <xsl:template match=
      "Order
         [generate-id()
         =
          generate-id(key('kOrderByNum', ManifestNo)[1])
          ]">
      <Order>
        <xsl:copy-of select="ManifestNo|Warehouse"/>

        <xsl:apply-templates select=
        "key('kSeqByOrderNo', ManifestNo)
          [generate-id()
          =
           generate-id(key('kSeqInOrder',
                           concat(../ManifestNo, '+', .)
                           )[1]
                      )
           ]
        "/>
      </Order>
     </xsl:template>

     <xsl:template match="SequenceNo[true()]">
      <Stop>
        <xsl:copy-of select="."/>
        <xsl:apply-templates mode="inGroup" select=
        "key('kSeqInOrder',
              concat(../ManifestNo, '+', .))"/>
      </Stop>
     </xsl:template>

     <xsl:template match="SequenceNo" mode="inGroup">
      <Freight>
        <xsl:copy-of select="../CustomerOrderNo|../Weight"/>
      </Freight>
     </xsl:template>
   </xsl:stylesheet>

在所提供的XML文档上应用时的

代码语言:javascript
复制
<Orders>
  <Order>
    <ManifestNo>283749</ManifestNo>
    <Warehouse>35</Warehouse>
    <SequenceNo>1</SequenceNo>
    <CustomerOrderNo>3524771-01</CustomerOrderNo>
    <Weight>180</Weight>
  </Order>
  <Order>
    <ManifestNo>283749</ManifestNo>
    <Warehouse>35</Warehouse>
    <SequenceNo>1</SequenceNo>
    <CustomerOrderNo>3524771-02</CustomerOrderNo>
    <Weight>250</Weight>
  </Order>
  <Order>
    <ManifestNo>283749</ManifestNo>
    <Warehouse>35</Warehouse>
    <SequenceNo>2</SequenceNo>
    <CustomerOrderNo>3524728-01</CustomerOrderNo>
    <Weight>25</Weight>
    </Order>
  <Order>
    <ManifestNo>283750</ManifestNo>
    <Warehouse>50</Warehouse>
    <SequenceNo>1</SequenceNo>
    <CustomerOrderNo>5464565-01</CustomerOrderNo>
    <Weight>150</Weight>
  </Order>
  <Order>
    <ManifestNo>283750</ManifestNo>
    <Warehouse>50</Warehouse>
    <SequenceNo>2</SequenceNo>
    <CustomerOrderNo>5874565-02</CustomerOrderNo>
    <Weight>125</Weight>
  </Order>
  <Order>
    <ManifestNo>283750</ManifestNo>
    <Warehouse>50</Warehouse>
    <SequenceNo>2</SequenceNo>
    <CustomerOrderNo>3524888-01</CustomerOrderNo>
    <Weight>95</Weight>
  </Order>
</Orders>

会生成想要的正确结果:

代码语言:javascript
复制
<Orders>
   <Order>
      <ManifestNo>283749</ManifestNo>
      <Warehouse>35</Warehouse>
      <Stop>
         <SequenceNo>1</SequenceNo>
         <Freight>
            <CustomerOrderNo>3524771-01</CustomerOrderNo>
            <Weight>180</Weight>
         </Freight>
         <Freight>
            <CustomerOrderNo>3524771-02</CustomerOrderNo>
            <Weight>250</Weight>
         </Freight>
      </Stop>
      <Stop>
         <SequenceNo>2</SequenceNo>
         <Freight>
            <CustomerOrderNo>3524728-01</CustomerOrderNo>
            <Weight>25</Weight>
         </Freight>
      </Stop>
   </Order>
   <Order>
      <ManifestNo>283750</ManifestNo>
      <Warehouse>50</Warehouse>
      <Stop>
         <SequenceNo>1</SequenceNo>
         <Freight>
            <CustomerOrderNo>5464565-01</CustomerOrderNo>
            <Weight>150</Weight>
         </Freight>
      </Stop>
      <Stop>
         <SequenceNo>2</SequenceNo>
         <Freight>
            <CustomerOrderNo>5874565-02</CustomerOrderNo>
            <Weight>125</Weight>
         </Freight>
         <Freight>
            <CustomerOrderNo>3524888-01</CustomerOrderNo>
            <Weight>95</Weight>
         </Freight>
      </Stop>
   </Order>
</Orders>

II. XSLT2.0解决方案

代码语言:javascript
复制
<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kSeqByOrderNo" match="SequenceNo"
      use="../ManifestNo"/>

 <xsl:template match="/*">
   <Orders>
     <xsl:for-each-group select="Order" group-by="ManifestNo">
      <Order>
        <xsl:copy-of select="ManifestNo|Warehouse"/>

        <xsl:for-each-group select="key('kSeqByOrderNo', ManifestNo)"
         group-by=".">
         <xsl:copy-of select="."/>
         <Stop>
          <xsl:apply-templates select="current-group()"/>
         </Stop>
        </xsl:for-each-group>
      </Order>
     </xsl:for-each-group>
   </Orders>
 </xsl:template>

 <xsl:template match="SequenceNo">
   <Freight>
     <xsl:copy-of select="../CustomerOrderNo|../Weight"/>
   </Freight>
 </xsl:template>
</xsl:stylesheet>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10558164

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档