Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XSLT-php将XML转换为XML_Xml_Xslt - Fatal编程技术网

使用XSLT-php将XML转换为XML

使用XSLT-php将XML转换为XML,xml,xslt,Xml,Xslt,我想通过xslt使用php将xml文件转换成另一个文件。 对于输出,我需要一些调整,但我不知道如何调整xsl样式表 谢谢你的帮助 对产出进行必要的调整: 向category元素添加动态计数,如 将产品元素大小/颜色/颜色/可用大小的所有内容添加到元素,如S:M:L:XL L:M 向图像元素添加动态计数,如 源xml: <?xml version="1.0" encoding="utf-8"?> <PRODUCTS> <PRODUCT> <COD

我想通过xslt使用php将xml文件转换成另一个文件。 对于输出,我需要一些调整,但我不知道如何调整xsl样式表

谢谢你的帮助

对产出进行必要的调整:

  • 向category元素添加动态计数,如
  • 将产品元素大小/颜色/颜色/可用大小的所有内容添加到
    元素,如
    S:M:L:XL L:M
  • 向图像元素添加动态计数,如
源xml:

<?xml version="1.0" encoding="utf-8"?>
<PRODUCTS>
 <PRODUCT>
  <CODE>19</CODE>
  <NAME>daisy</NAME>
  <MANUFACTURER>79</MANUFACTURER>
  <DESCRIPTION>t-shirt</DESCRIPTION>
  <SIZES></SIZES>
  <PRICE>33.33</PRICE>
  <PRICE_AKCIA>24.17</PRICE_AKCIA>
  <CATEGORY_ID>42</CATEGORY_ID>
  <CATEGORIES>
    <CATEGORY>clothes</CATEGORY>
    <CATEGORY>t-shirt</CATEGORY>
    <CATEGORY>latest</CATEGORY>
  </CATEGORIES>
  <COLORS>
   <COLOR>
    <NAME>green</NAME>
    <IMAGE>http://www.xyz.com/userfiles/daisy_green.png</IMAGE>
    <AVAILABLE_SIZES>
     <SIZE>S</SIZE>
     <SIZE>M</SIZE>
    </AVAILABLE_SIZES>
    <SIZES>
     <SIZE>S</SIZE>
     <SIZE>M</SIZE>
     <SIZE>L</SIZE>
     <SIZE>XL</SIZE>
    </SIZES>
   </COLOR>
   <COLOR>
    <NAME>orange</NAME>
    <IMAGE>http://www.xyz.com/userfiles/daisy_orange.png</IMAGE>
    <AVAILABLE_SIZES>
     <SIZE>L</SIZE>
     <SIZE>M</SIZE>
    </AVAILABLE_SIZES>
    <SIZES>
     <SIZE>S</SIZE>
     <SIZE>M</SIZE>
     <SIZE>L</SIZE>
     <SIZE>XL</SIZE>
    </SIZES>
   </COLOR>
  </COLORS>
 </PRODUCT>
</PRODUCTS>
xsl样式表:

<?xml version="1.0" encoding="utf-8"?>
<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:template match="/">
    <xsl:element name="products">
        <xsl:apply-templates select="PRODUCTS/PRODUCT"/>
    </xsl:element>
</xsl:template>

<xsl:template match="PRODUCTS/PRODUCT"> 
    <xsl:element name="product">
        <xsl:element name="id">
            <xsl:value-of select="CODE"/>
        </xsl:element>
        <xsl:element name="name">
            <xsl:value-of select="NAME"/>
        </xsl:element>
        <xsl:element name="model">
            <xsl:value-of select="CODE"/>
        </xsl:element>
        <xsl:element name="manufacturer">
            <xsl:value-of select="MANUFACTURER"/>
        </xsl:element>
        <xsl:element name="category_id">
            <xsl:value-of select="CATEGORY_ID"/>
        </xsl:element>
        <xsl:apply-templates select="CATEGORIES"/>
        <xsl:element name="description">
            <xsl:value-of select="DESCRIPTION"/>
        </xsl:element>
        <xsl:element name="price">
            <xsl:value-of select="PRICE"/>
        </xsl:element>
        <xsl:element name="special">
            <xsl:value-of select="PRICE_AKCIA"/>
        </xsl:element>
        <xsl:apply-templates select="COLORS/COLOR"/>
        <xsl:apply-templates select="COLORS"/>
    </xsl:element>
</xsl:template>

<xsl:template match="CATEGORIES">
    <xsl:for-each select="CATEGORY">    
      <xsl:element name="category">
        <xsl:value-of select="."/>
      </xsl:element>
    </xsl:for-each>
</xsl:template>

<xsl:template match="COLORS">
    <xsl:for-each select="COLOR/NAME">    
      <xsl:variable name="color" select="." />
      <xsl:element name="{$color}">
        <xsl:apply-templates select="COLOR/AVAILABLE_SIZES"/>
      </xsl:element>
    </xsl:for-each>
</xsl:template>

<xsl:template match="COLORS/COLOR">
    <xsl:for-each select="IMAGE">    
      <xsl:element name="image">
        <xsl:value-of select="."/>
      </xsl:element>
    </xsl:for-each>
</xsl:template>

<xsl:template match="COLOR/AVAILABLE_SIZES">
    <xsl:for-each select="SIZE">    
      <xsl:value-of select="."/>:
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

:
结果:

<?xml version="1.0" encoding="UTF-8"?>
<products>
  <product>
    <id>19</id>
    <name>daisy</name>
    <model>19</model>
    <manufacturer>79</manufacturer>
    <category_id>42</category_id>
    <category>clothes</category>
    <category>t-shirt</category>
    <category>latest</category>
    <description>t-shirt</description>
    <price>33.33</price>
    <special>24.17</special>
    <image>http://www.xyz.com/userfiles/daisy_green.png</image>
    <image>http://www.xyz.com/userfiles/daisy_orange.png</image>
    <green/>
    <orange/>
  </product>
</products>

19
雏菊
19
79
42
衣服
T恤
最新的
T恤
33.33
24.17
http://www.xyz.com/userfiles/daisy_green.png
http://www.xyz.com/userfiles/daisy_orange.png

如果要动态命名元素,可以使用属性值模板指定元素名称

因此,如果您想要类别1类别2,等等,而不仅仅是类别,您可以这样做

 <xsl:element name="category{position()}">

大括号表示这是一个要求值的表达式

但是,如果您直接使用图像代码执行此操作,您将看到它们的后缀都是1

<xsl:template match="COLORS/COLOR">
    <xsl:for-each select="IMAGE">    
      <xsl:element name="image{position()}">
        <xsl:value-of select="."/>
      </xsl:element>
    </xsl:for-each>
</xsl:template>

这是因为您得到的是图像元素在颜色元素中的位置。确实需要父元素颜色的位置。相反,在这里匹配COLORS元素可能更好,然后您可以得到COLOR元素的位置

<xsl:template match="COLORS">
    <xsl:for-each select="COLOR">    
      <xsl:element name="image{position()}">
        <xsl:value-of select="IMAGE"/>
      </xsl:element>
    </xsl:for-each>
</xsl:template>

当然,这意味着您将得到两个匹配颜色的模板,因此您可能希望将它们组合起来。但是,另一个模板存在问题。您正在迭代COLOR/NAME,这意味着您将位于循环中的NAME元素上。因此,当您尝试选择颜色/可用大小时,它会在当前元素下方查找它们,而当前元素不存在。你应该这么做

<xsl:template match="COLORS">
    <xsl:for-each select="COLOR">    
      <xsl:variable name="color" select="NAME" />
      <xsl:element name="{$color}">
        <xsl:apply-templates select="AVAILABLE_SIZES"/>
      </xsl:element>
    </xsl:for-each>

    <!-- Code to do images from above -->
</xsl:template>

还有几件事需要注意。如果需要动态元素名(如上图所示),只需使用xsl:element,否则直接输出元素即可

此外,在许多情况下,您所做的只是将大写名称转换为小写名称。使用通用模板可能更简单

<xsl:template match="*">
   <xsl:element name="{translate(
         local-name(), 
         'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
         'abcdefghijklmnopqrstuvwxyz')}">
      <xsl:apply-templates />
     </xsl:element>
</xsl:template>

这将减少您需要编写的代码。当您想要将元素名称更改为完全不同的名称时,您只需要特定的模板

尝试以下XSLT

<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:template match="*">
      <xsl:element name="{translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')}">
         <xsl:apply-templates/>
      </xsl:element>
   </xsl:template>

   <xsl:template match="CODE">
      <id>
         <xsl:value-of select="."/>
      </id>
   </xsl:template>

   <xsl:template match="PRICE_AKCIA">
      <special>
         <xsl:value-of select="."/>
      </special>
   </xsl:template>

   <xsl:template match="CATEGORIES">
      <xsl:for-each select="CATEGORY">
         <xsl:element name="category{position()}">
            <xsl:value-of select="."/>
         </xsl:element>
      </xsl:for-each>
   </xsl:template>

   <xsl:template match="COLORS">
      <xsl:for-each select="COLOR">
         <xsl:variable name="color" select="NAME"/>
         <xsl:element name="{$color}">
            <xsl:apply-templates select="AVAILABLE_SIZES"/>
         </xsl:element>
      </xsl:for-each>
      <xsl:for-each select="COLOR">
         <xsl:element name="image{position()}">
            <xsl:value-of select="IMAGE"/>
         </xsl:element>
      </xsl:for-each>
   </xsl:template>

   <xsl:template match="AVAILABLE_SIZES">
      <xsl:for-each select="SIZE">
         <xsl:if test="position() > 1">:</xsl:if>
         <xsl:value-of select="."/>
      </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

:
当应用于示例XML时,将输出以下内容

<products>
   <product>
      <id>19</id>
      <name>daisy</name>
      <manufacturer>79</manufacturer>
      <description>t-shirt</description>
      <sizes/>
      <price>33.33</price>
      <special>24.17</special>
      <category_id>42</category_id>
      <category1>clothes</category1>
      <category2>t-shirt</category2>
      <category3>latest</category3>
      <green>S:M</green>
      <orange>L:M</orange>
      <image1>http://www.xyz.com/userfiles/daisy_green.png</image1>
      <image2>http://www.xyz.com/userfiles/daisy_orange.png</image2>
   </product>
</products>

19
雏菊
79
T恤
33.33
24.17
42
衣服
T恤
最新的
S:M
L:M
http://www.xyz.com/userfiles/daisy_green.png
http://www.xyz.com/userfiles/daisy_orange.png

你好!您是否也可以添加您的预期输出,因为这样可以更清楚地了解您的需求?谢谢请再说一件事,如果颜色的名称有两个词,例如浅蓝色,元素必须命名为浅蓝色,因为转换时出错。请,如何避免这种情况?这是直截了当的,使用“translate”函数将空格替换为下划线。如果你不能马上解决这个问题,最好问一个全新的问题,因为这个问题已经相当大了。谢谢