簡體   English   中英

如何通過XSLT將兩個並行的XML結構映射在一起?

[英]How can I map two side by side XML structures together via XSLT?

我正在獲取一個XML文件,需要將其轉換為另一種標准類型。 XSLT2觸手可及,我無法控制任何一個文件的格式。 第一個有兩個序列,兩個序列使用數字值進行匹配。 第一個序列可以具有第二個序列的0..n。

一個例子是:

輸入:

<foo>
<structure name="items">
    <item>
        <itemCode>1</itemCode>
        <itemValue>1111</itemValue>
    </item>
    <item>
        <itemCode>2</itemCode>
        <itemValue>2222</itemValue>
    </item>
</structure>
<structure name="subItems">
    <subItem>
        <itemCode>1</itemCode>
        <subValue>12</subValue>
        <subType>MISC</subType>
    </subItem>
    <subItem>
        <itemCode>1</itemCode>
        <subValue>15</subValue>
        <subType>MISC2</subType>
    </subItem>
    <subItem>
        <itemCode>2</itemCode>
        <subValue>40</subValue>
        <subType>MISC</subType>
    </subItem>
</structure>
</foo>

我想要的輸出是

<bar>
<items>
    <item>
        <code>1</code>
        <value>1111</value>
        <subItems>
            <subItem>
                <subValue>12</subValue>
                <subType>MISC</subType>
            </subItem>
            <subItem>
                <subValue>15</subValue>
                <subType>MISC2</subType>
            </subItem>              
        </subItems>
    </item> 
    <item>
        <code>2</code>
        <value>2222</value>
        <subItems>
            <subItem>
                <subValue>40</subValue>
                <subType>MISC</subType>
            </subItem>
        </subItems>
    </item>         
</items>
</bar>

我一直沒有成功將item.itemCode映射到subItem.itemCode,這僅僅是因為XSLT處理器似乎在看到下一個序列之前退出了第一個序列。 我無法知道這兩個序列將得到多少,因此我無法進行靜態映射。

有任何想法嗎?

提前致謝

選擇適當的子值的另一種方法是使用鍵:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
  <xsl:key name="subitems-by-code" match="subItem" use="itemCode"/>

  <xsl:template match="foo">
    <bar>
      <items>
        <xsl:apply-templates select="structure[@name='items']"/>
      </items>
    </bar>
  </xsl:template>

  <xsl:template match="item">
    <item>
      <xsl:copy-of select="*"/>
      <subItems>
        <xsl:apply-templates select="key('subitems-by-code', itemCode)"/>
      </subItems>
    </item>
  </xsl:template>

  <xsl:template match="subItem">
    <subItem>
      <xsl:copy-of select="subValue|subType"/>
    </subItem>
  </xsl:template>
</xsl:stylesheet>

我通常不滿意發布完整的解決方案,但是問題看起來很有趣,所以我寫了這篇。

請再次詢問是否需要詳細說明。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/foo">
        <bar>
            <items>
                <xsl:apply-templates select="structure[@name='items']/item">
                    <xsl:sort select="itemCode" />
                </xsl:apply-templates>
            </items>
        </bar>
    </xsl:template>

    <xsl:template match="item">

            <item>
                <code>
                    <xsl:value-of select="itemCode" />
                </code>
                <value>
                    <xsl:value-of select="itemValue" />
                </value>
                <subItems>
                    <xsl:apply-templates select="/foo/structure[@name='subItems']/subItem[itemCode=current()/itemCode]" />
                </subItems>
            </item>

    </xsl:template>

    <xsl:template match="subItem">

        <subItem>
            <xsl:copy-of select="subValue"/>
            <xsl:copy-of select="subType"/>
        </subItem>

    </xsl:template>

</xsl:stylesheet>

輸出

<?xml version="1.0" encoding="utf-8"?>
<bar>
   <items>
      <item>
         <code>1</code>
         <value>1111</value>
         <subItems>
            <subItem>
               <subValue>12</subValue>
               <subType>MISC</subType>
            </subItem>
            <subItem>
               <subValue>15</subValue>
               <subType>MISC2</subType>
            </subItem>
         </subItems>
      </item>
      <item>
         <code>2</code>
         <value>2222</value>
         <subItems>
            <subItem>
               <subValue>40</subValue>
               <subType>MISC</subType>
            </subItem>
         </subItems>
      </item>
   </items>
</bar>

在我看來,這就像一個簡單的分組問題。

<xsl:for-each-group select="items/item, subItems/subItem" group-by="itemCode">
  <item>
    <code><xsl:value-of select="current-group()[self::item]/itemCode"/></code>
    <value><xsl:value-of select="current-group()/itemValue"/></value>
    <subItems>
      <xsl:copy-of select="current-group()[self::subItem]/(subValue, subType)"/>
    </subItems>
  </item>
</xsl:for-each-group>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM