【问题标题】:need to put repeating XML nodes in separate nodes with the help of xsl / xslt需要借助 xsl / xslt 将重复的 XML 节点放在单独的节点中
【发布时间】:2019-09-06 21:15:33
【问题描述】:

我有这个 xml:

<products>
 <product>
 <name>ad</name>
 <category>something</category>
 <path>something</path>
    <size>S</size>
    <color-code>87-3</color-code>
    <size-code>24294</size-code>
    <size-qty>10</size-qty>
    <size-codeproducer>5902228002604</size-codeproducer>
    <size>M</size>
    <color-code>87-4</color-code>
    <size-code>24295</size-code>
    <size-qty>64</size-qty>
    <size-codeproducer>5902228002611</size-codeproducer>
    <size>L</size>
    <color-code>87-5</color-code>
    <size-code>24296</size-code>
    <size-qty>46</size-qty>
    <size-codeproducer>5902228002628</size-codeproducer>
    <size>XXL</size>
    <color-code>87-7</color-code>
    <size-code>24298</size-code>
    <size-qty>0</size-qty>
    <size-codeproducer>5902228002635</size-codeproducer>
    <imgs>
      <img>pictures/large/7/8/87_2.jpg</img>
      <img>pictures/large/7/8/87_1.jpg</img>
      <img>pictures/large/7/8/87_4.jpg</img>
      <img>pictures/large/7/8/87_5.jpg</img>
      <img>pictures/large/7/8/87_3.jpg</img>
      <img>pictures/large/7/8/87_6.jpg</img>
    </imgs>google.com</url>
    <price>7.98</price>
    <brand>NIKE</brand>
    <color>black</color>
    <gender>Man</gender>
  </product>
  <product>
  ...
  ...
  ...
  </product>
</products>

我需要什么:

<products>
<product>
<name>ad</name>
<category>something</category>
...
<variation>
   <size>S</size>
   <color-code>87-3</color-code>
   <size-code>24294</size-code>
   <size-qty>10</size-qty>
   <size-codeproducer>5902228002604</size-codeproducer>
</variation>
<variation>
   <size>M</size>
   <color-code>87-4</color-code>
   <size-code>24295</size-code>
   <size-qty>64</size-qty>
   <size-codeproducer>5902228002611</size-codeproducer>
</variation>
<variation>
   <size>L</size>
   <color-code>87-5</color-code>
   <size-code>24296</size-code>
   <size-qty>46</size-qty>
   <size-codeproducer>5902228002628</size-codeproducer>
</variation>
<variation>
   <size>XXL</size>
   <color-code>87-7</color-code>
   <size-code>24298</size-code>
   <size-qty>0</size-qty>
   <size-codeproducer>5902228002635</size-codeproducer>
</variation>
</product>
<product>
...
</product>
</products>

我有这个 xsl:

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

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

     <xsl:template match="/products/product">

        <xsl:copy>
            <xsl:copy-of select="description|id|name|category|path"/>
            <xsl:for-each select="/products/product/size">
                <variation>
                    <xsl:variable name="occur" select="position()"/>
                    <xsl:copy-of select="."/>
                    <xsl:copy-of select="/products/product/color-code[$occur]"/>
                    <xsl:copy-of select="/products/product/size-code[$occur]"/>
                    <xsl:copy-of select="/products/product/size-qty[$occur]"/>
                    <xsl:copy-of select="/products/product/size-codeproducer[$occur]"/>
                </variation>
            </xsl:for-each>
            <xsl:copy-of select="imgs|url|price|brand|color|gender"/>
        </xsl:copy>

     </xsl:template>
</xsl:stylesheet>

结果是一个复制的xml文件 size-codeproducer,color-code,size-codesize-qty 在每个产品节点中。 任何帮助将不胜感激。

我尝试了各种 xsl 复制变体 - for-each 循环和其他东西,但其中大多数在解析后没有打印任何内容,打印了相同的文档或存在其他问题。我猜问题是我正在使用的路径(xpaths?)。

【问题讨论】:

    标签: php xml xslt xslt-1.0


    【解决方案1】:

    首先你的xsl:for-each有问题...

    <xsl:for-each select="/products/product/size">
    

    通过以代表文档节点的/ 开始选择表达式,您实际上是在进行绝对搜索,而忽略了您当前定位的product。您应该这样做,以获取当前产品的 size 元素

    <xsl:for-each select="size">
    

    同样,对于各种xsl:copy-of 语句,而不是这样做...

    <xsl:copy-of select="/products/product/color-code[$occur]"/>
    

    你应该这样做(.. 获取当前size 元素的父元素)

    <xsl:copy-of select="../color-code[$occur]"/>
    

    试试这个模板

     <xsl:template match="/products/product">
        <xsl:copy>
            <xsl:copy-of select="description|id|name|category|path"/>
            <xsl:for-each select="size">
                <variation>
                    <xsl:variable name="occur" select="position()"/>
                    <xsl:copy-of select="."/>
                    <xsl:copy-of select="../color-code[$occur]"/>
                    <xsl:copy-of select="../size-code[$occur]"/>
                    <xsl:copy-of select="../size-qty[$occur]"/>
                    <xsl:copy-of select="../size-codeproducer[$occur]"/>
                </variation>
            </xsl:for-each>
            <xsl:copy-of select="imgs|url|price|brand|color|gender"/>
        </xsl:copy>
     </xsl:template>
    

    (请注意,您也可以在此处使用&lt;xsl:copy-of select="following-sibling::color-code[1]"/&gt;,其他语句也是如此)。

    【讨论】:

      【解决方案2】:

      只是为了展示另一种对相邻对象进行分组或从 XSLT 1.0 中的某些内容开始的方法,此样式表:

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          <xsl:template match="node()|@*" name="shallow-copy">
           <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
           </xsl:copy>
           <xsl:apply-templates select="following-sibling::node()[1]"/>
          </xsl:template>
      
          <xsl:template match="size">
           <variation>
            <xsl:call-template name="group-starting-with"/>
           </variation>
           <xsl:apply-templates select="following-sibling::node()[1]"/>
          </xsl:template>
      
          <xsl:template match="color-code|size-code|size-qty|size-codeproducer">
           <xsl:apply-templates select="following-sibling::node()[1]"/>
          </xsl:template>
      
          <xsl:template match="node()" mode="group-starting-with"
            name="group-starting-with">
            <xsl:copy>
             <xsl:apply-templates select="node()[1]|@*"/>
            </xsl:copy>
            <xsl:apply-templates select="following-sibling::node()[1]" 
             mode="group-starting-with"/>
          </xsl:template>
      
          <xsl:template match="size|imgs" mode="group-starting-with"/>
      </xsl:stylesheet>
      

      输出

      <products> 
        <product> 
          <name>ad</name>  
          <category>something</category>  
          <path>something</path>  
          <variation> 
            <size>S</size>  
            <color-code>87-3</color-code>  
            <size-code>24294</size-code>  
            <size-qty>10</size-qty>  
            <size-codeproducer>5902228002604</size-codeproducer> 
          </variation>  
          <variation> 
            <size>M</size>  
            <color-code>87-4</color-code>  
            <size-code>24295</size-code>  
            <size-qty>64</size-qty>  
            <size-codeproducer>5902228002611</size-codeproducer> 
          </variation>  
          <variation> 
            <size>L</size>  
            <color-code>87-5</color-code>  
            <size-code>24296</size-code>  
            <size-qty>46</size-qty>  
            <size-codeproducer>5902228002628</size-codeproducer> 
          </variation>  
          <variation> 
            <size>XXL</size>  
            <color-code>87-7</color-code>  
            <size-code>24298</size-code>  
            <size-qty>0</size-qty>  
            <size-codeproducer>5902228002635</size-codeproducer> 
          </variation>  
          <imgs> 
            <img>pictures/large/7/8/87_2.jpg</img>  
            <img>pictures/large/7/8/87_1.jpg</img>  
            <img>pictures/large/7/8/87_4.jpg</img>  
            <img>pictures/large/7/8/87_5.jpg</img>  
            <img>pictures/large/7/8/87_3.jpg</img>  
            <img>pictures/large/7/8/87_6.jpg</img> 
          </imgs>  
          <url>google.com</url>  
          <price>7.98</price>  
          <brand>NIKE</brand>  
          <color>black</color>  
          <gender>Man</gender> 
        </product>  
        <product>... ... ...</product> 
      </products>
      

      注意:这是在下面的斧头中穿越。这意味着每个规则都负责将模板应用于第一个孩子和第一个跟随兄弟。对于分组,您需要一个具有匹配标准的规则才能开始,空规则在不匹配标准时停止,并在标准匹配但您没有分组时绕过规则。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-10
        • 1970-01-01
        • 1970-01-01
        • 2018-12-18
        • 2019-04-11
        • 1970-01-01
        相关资源
        最近更新 更多