如何使用XSL将多个XML条目合并到一个树中

时间:2016-07-21 17:48:40

标签: xml xslt

我有一些XML,我试图用XSL进行重组。我对XSL很新,所以任何帮助都会受到赞赏。

我目前的XML是这样给我的。

<catalogItem>
  <partNumber>114-0015</partNumber>
  <itemName>This is Item 1</itemName>
  <price>$5.69</price>
</catalogItem>
<catalogItem>
  <partNumber>114-0016</partNumber>
  <itemName>This is Sub-item1</itemName>
  <price>$6.29</price>
  <parent>114-0015</parent>
</catalogItem>
<catalogItem>
  <partNumber>114-0017</partNumber>
  <itemName>This is Sub-item2</itemName>
  <price>$7.29</price>
  <parent>114-0015</parent>
</catalogItem>
<catalogItem>
  <partNumber>114-0018</partNumber>
  <itemName>This is Sub-item3</itemName>
  <price>$8.29</price>
  <parent>114-0015</parent>
</catalogItem>

我想知道是否可以对其进行重组,以便任何带有父标记的catalogItem都会插入到xml树结构中。请注意,父标记对应于该项父项的partNumber。所以我的最终输出是:

<catalogItem>
  <partNumber>114-0015</partNumber>
  <itemName>This is Item 1</itemName>
  <price>$5.69</price>
  <subitem>
    <subPartNumber>114-0016</subPartNumber>
    <subItemName>This is Sub-item1</subItemName>
    <subPrice>$6.29</subPrice>
  </subitem>
  <subitem>
    <subPartNumber>114-0017</subPartNumber>
    <subItemName>This is Sub-item2</subItemName>
    <subPrice>$7.29</subPrice>
  </subitem>
  <subitem>
    <subPartNumber>114-0018</subPartNumber>
    <subItemName>This is Sub-item3</subItemName>
    <subPrice>$8.29</subPrice>
  </subitem>
</catalogItem>

有人可以指出我正确的方向(希望提供一些代码示例),这将有助于我。 谢谢!

编辑:我还包括我当前使用的xslt进行其他一些转换。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
<dataroot>
  <xsl:for-each select="dataroot/catalogItem">
    <catalogItem>
    <xsl:if test="not(partNumber)"><Intro>
      <xsl:if test="not(partNumber)"><itemNameIntro><xsl:value-of select="itemName"/></itemNameIntro></xsl:if>
      <xsl:if test="not(partNumber)"><longDescriptionIntro><xsl:value-of select="longDescription"/></longDescriptionIntro></xsl:if>
      </Intro></xsl:if>
      <xsl:copy-of select="photo1"/>
      <xsl:copy-of select="categoryType"/>
      <xsl:copy-of select="bookSeries"/>
      <xsl:copy-of select="photo2"/>
      <xsl:copy-of select="photo3"/>
      <xsl:copy-of select="photo4"/>
      <xsl:copy-of select="logo"/>
      <xsl:if test="partNumber"><itemName><xsl:value-of select="itemName"/></itemName></xsl:if>
      <xsl:copy-of select="author"/>
      <xsl:if test="partNumber"><longDescription><xsl:value-of select="longDescription"/></longDescription></xsl:if>
      <xsl:if test="size1">
        <size1><xsl:value-of select="size1"/><xsl:if test="size1 and size2"> | </xsl:if></size1>
      </xsl:if>
      <xsl:copy-of select="size2"/>
      <xsl:if test="age">
        <age><xsl:if test="size1 and age or size2 and age"> | </xsl:if>age: <xsl:value-of select="age"/></age>
      </xsl:if>
      <xsl:if test="numberPages">
        <numberPages><xsl:value-of select="numberPages"/>p </numberPages>
      </xsl:if>
      <xsl:copy-of select="partNumber"/>
      <xsl:if test="price">
        <pricetab>  $</pricetab>
      </xsl:if>
      <xsl:if test="price">
        <price><xsl:value-of select="price"/></price>
      </xsl:if>
    </catalogItem>
  </xsl:for-each>
</dataroot>

1 个答案:

答案 0 :(得分:0)

您当前的XML&#34;根本不是XML,因为它没有单个根元素。

给定格式良好的XML输入,例如:

<catalog>
  <catalogItem>
    <partNumber>114-0015</partNumber>
    <itemName>This is Item 1</itemName>
    <price>$5.69</price>
  </catalogItem>
  <catalogItem>
    <partNumber>114-0016</partNumber>
    <itemName>This is Sub-item1</itemName>
    <price>$6.29</price>
    <parent>114-0015</parent>
  </catalogItem>
  <catalogItem>
    <partNumber>114-0017</partNumber>
    <itemName>This is Sub-item2</itemName>
    <price>$7.29</price>
    <parent>114-0015</parent>
  </catalogItem>
  <catalogItem>
    <partNumber>114-0018</partNumber>
    <itemName>This is Sub-item3</itemName>
    <price>$8.29</price>
    <parent>114-0015</parent>
  </catalogItem>
</catalog>

以下样式表:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="child" match="catalogItem" use="parent" />

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

<xsl:template match="/catalog">
    <xsl:copy>
        <xsl:apply-templates select="catalogItem[not(parent)]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="catalogItem">
    <xsl:copy>
        <xsl:apply-templates/>
        <xsl:apply-templates select="key('child', partNumber)" mode="sub"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="catalogItem" mode="sub">
    <subitem>
    <subPartNumber>
        <xsl:value-of select="partNumber"/>
    </subPartNumber>
    <subItemName>
        <xsl:value-of select="itemName"/>   
    </subItemName>
    <subPrice>
        <xsl:value-of select="price"/>  
    </subPrice>
    </subitem>
</xsl:template>

</xsl:stylesheet>

将返回:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
   <catalogItem>
      <partNumber>114-0015</partNumber>
      <itemName>This is Item 1</itemName>
      <price>$5.69</price>
      <subitem>
         <subPartNumber>114-0016</subPartNumber>
         <subItemName>This is Sub-item1</subItemName>
         <subPrice>$6.29</subPrice>
      </subitem>
      <subitem>
         <subPartNumber>114-0017</subPartNumber>
         <subItemName>This is Sub-item2</subItemName>
         <subPrice>$7.29</subPrice>
      </subitem>
      <subitem>
         <subPartNumber>114-0018</subPartNumber>
         <subItemName>This is Sub-item3</subItemName>
         <subPrice>$8.29</subPrice>
      </subitem>
   </catalogItem>
</catalog>