0

我试图使用 XSLT 对 XML 进行多次传递转换到另一个 xml。但无法实现。代码的帮助表示赞赏。

如果没有元素匹配并且@DimitreNovaatchev 进行muenchian 分组,我已经解决了提供的解决方案。在这种情况下,“” Car_MNO, Car_Model “”被匹配,然后其他值被分组。

Input XML:

<t>
<Vehicle>
<Car_MNo>123</Car_MNo>
<Car_Model>Audi</Car_Model>
<Description>car.color</Description>
<colour>BLACK</colour>
</Vehicle>

<Vehicle>
<Car_MNo>123</Car_MNo>
<Car_Model>Audi</Car_Model>
<Description>car.hood</Description>
<colour>RED</colour>
</Vehicle>

<Vehicle>
<Car_MNo>123</Car_MNo>
<Car_Model>BMW</Car_Model>
<Description>Bus.Brakes</Description>
<colour>steel</colour>
</Vehicle>

<Vehicle>
<Car_MNo>123</Car_MNo>
<Car_Model>BMW</Car_Model>
<Description>Bus.steering</Description>
<colour>black</colour>
</Vehicle>

<Vehicle>
<Car_MNo>234</Car_MNo>
<Car_Model>benz</Car_Model>
<Description>cycle.color</Description>
<colour>violet</colour>
</Vehicle>

<Vehicle>
<Car_MNo>345</Car_MNo>
<Car_Model>nissan</Car_Model>
<Description>bike.seat</Description>
<colour>RED</colour>
</Vehicle>

<Vehicle>
<Car_MNo>345</Car_MNo>
<Car_Model>nissan</Car_Model>
<Description>car</Description>
<colour>RED</colour>
</Vehicle>
</t>

XML 中的预期输出:

 <t>
  <Vehicle>
    <car>
      <color>BLACK</color>
      <hood>RED</hood>
    </car>
    <Bus>
     <Brakes>steel</Brakes>
     <Steering>black</Steering>
    </Bus>
    <cycle>
      <color>violet</color>
    </cycle>
    <bike>
      <seat>Red</seat>
    </bike>
  </Vehicle>
  <vehicle>
    <car>red</car>
 </vehicle>
</t>

我工作的示例代码如下所示:

<Vehicle>
  <xsl:variable name="vrtfPass2">
<xsl:apply-templates/>
  </xsl:variable>
  <xsl:apply-templates mode="pass3" select="ext:node-set($vrtfPass2)/* [generate-id()=generate-      id(key('kvehiclechild', name(Name/*[1]))[1])]   "/>
  <xsl:for-each select="//Vehicle">
  <xsl:if test="not(contains(Description,'.'))">
  <xsl:variable name="var3" select="Description"/>
  <xsl:element name="{$var3}">
  <xsl:value-of select="colour"/>
  </xsl:element>
  </xsl:if>
  </xsl:for-each>
  </Vehicle>
  <Vehicle>
  <xsl:variable name="vrtfPass3">
  <xsl:apply-templates/>
  </xsl:variable>
  <xsl:apply-templates mode="pass4" select="ext:node-set($vrtfPass3)/* [generate-id()= generate-      id(key('kvehicle_au', name(Description/*[1]))[1])]   "/>
  </Vehicle>

  <xsl:template match="Vehicle">
   <Vehicle>
    <car>
<xsl:if test="contains(Description,'.')">
  <xsl:element name="{concat(substring-before(Description, '.'),substring-after (Profile, ' '))}">
<xsl:element name="{substring-after(Description, '.')}">
<xsl:value-of select="Value"/>
</xsl:element>
</xsl:element>
</xsl:if>
     </car>
     </Vehicle>
     </xsl:template>
     <xsl:template match="Vehicle" mode="pass3">
     <xsl:apply-templates select="*/*[1]" mode="pass3"/>
     </xsl:template>
4

1 回答 1

0

这种转换(仍然是 2-pass :))

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

         <xsl:key name="kDescrByAttribs" match="Description"
          use="concat(../@Car_MNo, '+', ../@Car_Model)"/>

         <xsl:key name="kDescrChildByAttribsAndName" match="Description/*"
          use="concat(../../@Car_MNo, '+', ../../@Car_Model, '+', name())"/>

         <xsl:template match="/">
          <xsl:variable name="vrtfPass1">
            <xsl:apply-templates/>
          </xsl:variable>

          <xsl:apply-templates mode="pass2" select=
          "ext:node-set($vrtfPass1)/*/*
                   [generate-id()
                   =
                    generate-id(key('kDescrByAttribs', 
                                     concat(../@Car_MNo, '+', ../@Car_Model)
                                   )
                                    [1])
                   ]
          "/>

         </xsl:template>

         <xsl:template match="Vehicle[contains(Description, '.')]">
          <Vehicle Car_MNo="{Car_MNo}" Car_Model="{Car_Model}">
           <Description>
               <xsl:element name="{substring-before(Description, '.')}">
                 <xsl:element name="{substring-after(Description, '.')}">
                   <xsl:value-of select="colour"/>
                 </xsl:element>
               </xsl:element>
           </Description>
          </Vehicle>
         </xsl:template>

         <xsl:template match="Vehicle">
          <Vehicle Car_MNo="{Car_MNo}" Car_Model="{Car_Model}">
           <Description>
                 <xsl:element name="{Description}">
                   <xsl:value-of select="colour"/>
                 </xsl:element>
           </Description>
          </Vehicle>
         </xsl:template>

         <xsl:template match="Description" mode="pass2">
           <Description>
             <xsl:apply-templates mode="pass2" select=
              "*[generate-id()
                =
                generate-id(key('kDescrChildByAttribsAndName',
                                concat(../../@Car_MNo, 
                                      '+', ../../@Car_Model, 
                                      '+', name())
                               )[1]
                            )
                ]"/>
             <xsl:copy-of select=
              "key('kDescrByAttribs',
                   concat(../@Car_MNo, '+', ../@Car_Model)
                   )/*[not(*)]
              "/>

           </Description>
         </xsl:template>

         <xsl:template match="Description/*" mode="pass2">
           <xsl:element name="{name()}">
             <xsl:copy-of select=
              "key('kDescrChildByAttribsAndName',
                   concat(../../@Car_MNo, '+', ../../@Car_Model, '+', name())
                   )/*
              "/>
           </xsl:element>
         </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<t>
    <Vehicle>
        <Car_MNo>123</Car_MNo>
        <Car_Model>Audi</Car_Model>
        <Description>car.color</Description>
        <colour>BLACK</colour>
    </Vehicle>
    <Vehicle>
        <Car_MNo>123</Car_MNo>
        <Car_Model>Audi</Car_Model>
        <Description>car.hood</Description>
        <colour>RED</colour>
    </Vehicle>
    <Vehicle>
        <Car_MNo>123</Car_MNo>
        <Car_Model>BMW</Car_Model>
        <Description>Bus.Brakes</Description>
        <colour>steel</colour>
    </Vehicle>
    <Vehicle>
        <Car_MNo>123</Car_MNo>
        <Car_Model>BMW</Car_Model>
        <Description>Bus.steering</Description>
        <colour>black</colour>
    </Vehicle>
    <Vehicle>
        <Car_MNo>234</Car_MNo>
        <Car_Model>benz</Car_Model>
        <Description>cycle.color</Description>
        <colour>violet</colour>
    </Vehicle>
    <Vehicle>
        <Car_MNo>345</Car_MNo>
        <Car_Model>nissan</Car_Model>
        <Description>bike.seat</Description>
        <colour>RED</colour>
    </Vehicle>
    <Vehicle>
        <Car_MNo>345</Car_MNo>
        <Car_Model>nissan</Car_Model>
        <Description>car</Description>
        <colour>RED</colour>
    </Vehicle>
</t>

产生想要的正确结果:

<Description>
   <car>
      <color>BLACK</color>
      <hood>RED</hood>
   </car>
</Description>
<Description>
   <Bus>
      <Brakes>steel</Brakes>
      <steering>black</steering>
   </Bus>
</Description>
<Description>
   <cycle>
      <color>violet</color>
   </cycle>
</Description>
<Description>
   <bike>
      <seat>RED</seat>
   </bike>
   <car>RED</car>
</Description>
于 2012-07-06T21:52:55.857 回答