【问题标题】:XSL Pass Transformation- standard Muenchian groupingXSL Pass Transformation - 标准 Muenchian 分组
【发布时间】:2012-07-07 07:44:02
【问题描述】:

我试图使用 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>

【问题讨论】:

  • 该元素没有特定含义。我无法解释它的具体含义。相反,我将解释我感兴趣的主题。请记住我之前提出的问题是 2 遍转换的问题。现在我有兴趣通过比较“,”来获取输出,如果它们都匹配,那么输出必须通过分组显示。如果不匹配,它们必须在单独的元素中。我已经尝试过了,我得到了将相似元素分组为一个的输出,但另一个没有正确的期望输出。
  • Ramana:为什么结果中有两个Vehicle 元素?这没有解释,似乎不正确/任意。
  • 我制作了两个 Vehicle 元素,因为“当您检查输入的 xml 文件时,如果元素 ", " 匹配,则元素将进行 2 次转换并合并到一个单一的元素。“如果假设他们不匹配,他们将被分开”,因为您提供给我的结果是真实的。但是如果他们不匹配并且我有一个带有“否”的元素。 " 那么第二个 Vehicle 元素应该有结果。
  • @Dimitre:作为一个学习的开发者......应该在发布时提供准确的结果。是我的错。我真诚地道歉。
  • Ramana,对不起,但你的最后一个解释听起来甚至不像有意义的英语。这里有四种不同的车型:奥迪、宝马、奔驰和尼桑——您是如何决定只生成两个Vehicle 元素的?这是不合逻辑的和完全的谜。我强烈建议您回滚对原始问题的更改,然后用您的新问题提出一个新问题。您必须解释想要的结果背后的逻辑 - 以便人们能够理解这个解释。

标签: xml xslt xml-serialization xml-parsing


【解决方案1】:

这个转换(仍然是 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>

【讨论】:

  • 预期的输出与我给出的不同。您的输出的最后一列已合并。如果可能的话,你能检查一下并让我知道更新。我认为逻辑上存在细微差别。
  • @Ramana:恕我直言,你没有解释任何“逻辑”,所以这是我猜测的结果。我没有时间去研究这个没有经过深思熟虑的问题并一次又一次地猜测。
  • 我现在已经把这个问题做得非常完美了。我的预期输出是什么让你麻烦。我想我已经为我编辑的作品提供了逻辑。
  • @Ramana:为什么结果中有两个 Vehicle 元素?这没有解释,似乎不正确/任意
猜你喜欢
  • 1970-01-01
  • 2017-07-12
  • 2013-12-06
  • 2018-10-20
  • 1970-01-01
  • 1970-01-01
  • 2014-03-19
  • 2021-11-20
  • 2018-03-28
相关资源
最近更新 更多