使用XSLT将现有的多个转换为多个以反转多对多的关系

时间:2013-08-14 12:24:46

标签: xml xslt-1.0

你能帮我实现这个XSLT转型吗?这更像是扭转人际关系......

我有优惠/优惠* / TrimLine * / PRNumber * --->我想将其转换为PRNumbers / PRNumber * / TrimLine * / Offer *

输入:

    <offerStructures>
    <offerStructure>
        <productId>1</productId>
        <brandName>OS</brandName>
        <trimLines>
            <trimLine>
                <productId>12</productId>
                <trimLineName>12TL</trimLineName>
                <prNumbers>
                    <prNumber>
                        <productId>1</productId>
                        <countryCode>IN</countryCode>
                        <brandName>OKI</brandName>
                    </prNumber>
                    <prNumber>
                        <productId>2</productId>
                        <countryCode>US</countryCode>
                        <brandName>LOP</brandName>
                    </prNumber>
                </prNumbers>
            </trimLine>
            <trimLine>
                <productId>13</productId>
                <trimLineName>13TL</trimLineName>
                <prNumbers>
                    <prNumber>
                        <productId>1</productId>
                        <countryCode>IN</countryCode>
                        <brandName>PYU</brandName>
                    </prNumber>
                    <prNumber>
                        <productId>3</productId>
                        <countryCode>AU</countryCode>
                        <brandName>ABC</brandName>
                    </prNumber>
                </prNumbers>
            </trimLine>
        </trimLines>
    </offerStructure>
    ../Multiple Offer Structure
</offerStructures>

必需输出:

<prNumbers>
    <prNumber>
        <productId>1</productId>
        <countryCode>IN</countryCode>
        <brandName>PYU</brandName>
        <trimLine>
            <productId>13</productId>
            <trimLineName>13TL</trimLineName>
            <offerStructure>
                <productId></productId>
            </offerStructure>
            <offerStructure>
                <productId></productId>
            </offerStructure>
        </trimLine>
        <trimLine>
            <productId>12</productId>
            <trimLineName>12TL</trimLineName>
        </trimLine>
    </prNumber>
    <prNumber>
        <productId>2</productId>
        <countryCode>US</countryCode>
        <brandName>LOP</brandName>
        <trimLine>
            <productId>12</productId>
            <trimLineName>12TL</trimLineName>
            <offerStructure>
                <productId></productId>
            </offerStructure>
        </trimLine>
    </prNumber>
    <prNumber>
        <productId>3</productId>
        <countryCode>AU</countryCode>
        <brandName>ABC</brandName>
        <trimLine>
            <productId>13</productId>
            <trimLineName>13TL</trimLineName>
        </trimLine>
    </prNumber>
</prNumbers>

由于

1 个答案:

答案 0 :(得分:0)

这可能不是你需要的100%(因为你对你的要求比较模糊),但是

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes" />

  <xsl:key name="kPrNumber" match="prNumber" use="productId" />

  <xsl:template match="/">
    <prNumbers>
      <xsl:apply-templates select="//prNumber" mode="group" />
    </prNumbers>
  </xsl:template>

  <xsl:template match="prNumber" mode="group">
    <xsl:variable name="thisGroup" select="key('kPrNumber', productId)" />   

    <xsl:if test="generate-id() = generate-id($thisGroup[1])">
      <xsl:copy>
        <xsl:copy-of select="productId" />
        <xsl:copy-of select="countryCode" />
        <xsl:copy-of select="brandName" />
        <xsl:apply-templates select="$thisGroup/ancestor::trimLine" />
      </xsl:copy>
    </xsl:if>
  </xsl:template>

  <xsl:template match="trimLine">
    <xsl:copy>
      <xsl:copy-of select="productId" />
      <xsl:copy-of select="trimLineName" />
      <xsl:apply-templates select="ancestor::offerStructure" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="offerStructure">
    <xsl:copy>
      <xsl:copy-of select="productId" />
      <xsl:copy-of select="brandName" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

给你

<prNumbers>
  <prNumber>
    <productId>1</productId>
    <countryCode>IN</countryCode>
    <brandName>OKI</brandName>
    <trimLine>
      <productId>12</productId>
      <trimLineName>12TL</trimLineName>
      <offerStructure>
        <productId>1</productId>
        <brandName>OS</brandName>
      </offerStructure>
    </trimLine>
    <trimLine>
      <productId>13</productId>
      <trimLineName>13TL</trimLineName>
      <offerStructure>
        <productId>1</productId>
        <brandName>OS</brandName>
      </offerStructure>
    </trimLine>
  </prNumber>
  <prNumber>
    <productId>2</productId>
    <countryCode>US</countryCode>
    <brandName>LOP</brandName>
    <trimLine>
      <productId>12</productId>
      <trimLineName>12TL</trimLineName>
      <offerStructure>
        <productId>1</productId>
        <brandName>OS</brandName>
      </offerStructure>
    </trimLine>
  </prNumber>
  <prNumber>
    <productId>3</productId>
    <countryCode>AU</countryCode>
    <brandName>ABC</brandName>
    <trimLine>
      <productId>13</productId>
      <trimLineName>13TL</trimLineName>
      <offerStructure>
        <productId>1</productId>
        <brandName>OS</brandName>
      </offerStructure>
    </trimLine>
  </prNumber>
</prNumbers>

请注意,在第一个<prNumber>中,它会为您提供<brandName>OKI</brandName>。这是因为你的输入样本有几个branNames可供productId 1选择,这会使事情变得模棱两可。