2011-07-26 164 views
4

我希望您的帮助可以使用XSLT将某些XML转换为新的XML文件。我有选择多个XML并在其上应用XSLT的代码。如何将多个xml文件转换并合并为一个文件

我的问题是在XSLT中,我想将shop1.xml shop2xml ..转换为allshops.xml。对于知道如何使用XSLT的人来说,这是一件容易的事,因为只有2-3个变化。

下面您可以找到更好理解的结构。非常感谢你。

shop1.xml

<shop> 
    <products> 
     <product id="189"> 
      <title></title> 
      <description></description> 
      <price></price> 
      <image></image> 
      <url></url> 
      <category id="61"></category> 
     </product> 
    </products> 
</shop> 

shop2.xml

<shop> 
    <products>  
     <product id="182"> 
      <title></title> 
      <description></description> 
      <price></price> 
      <image></image> 
      <url></url> 
      <category id="62"></category> 
     </product> 
    </products> 
</shop> 

shop3.xml //这其中有直接的产品为根,ID可能是已经存在

<products> 
    <product> 
     <id>123</id> 
     <title></title> 
     <description></description> 
     <price></price> 
     <image></image> 
     <url></url> 
     <category id="62"></category> 
    </product>  
</products> 

paths.xml它从PHP代码用于获取多个XML文件

<?xml version="1.0" encoding="utf-8"?> 
<files> 
    <file>shop1.xml</file> 
    <file>shop2.xml</file> 
    <file>shop3.xml</file> 
</files> 

allshops.xml

<products> //removed the store,shop and products stays as root 
    <product> 
     <id>the product's attribute id</id> //new element, with value the product id="" 
     <title></title> 
     <description></description> 
     <price></price> 
     <image></image> 
     <url></url> 
     <category></category> //removed the attribute id 
     <shopid></shopid> //new element, will be blank for now 
    </product> 
    <product> 
    </product> 
    . 
    . 
    . 
</products> 
+0

这将是更好使用'文档加载的所有文件( )'XSLT 1.0函数。通过这种方式,您将能够正确地将内容包含在一个'products'root中,并且可以用当前文件名填充'shopid'。 –

+0

你好。如果您需要回复,我对此解决方案非常感兴趣。 – EnexoOnoma

+0

看到我的答案。我保留了一般变换,以便包含最终不包含在输入样本中的其他节点。希望能帮助到你。 –

回答

6

按照要求,在这里它融合了外部纯XSLT解决方案使用document() XSLT 1.0函数的文件。

注:


[XSLT 1.0]

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:include href="identity.xsl"/> 

    <xsl:template match="/*"> 
     <products> 
      <xsl:for-each select="file"> 
       <xsl:apply-templates 
        select="document(.)/*//product"> 
        <xsl:with-param name="file" select="."/> 
       </xsl:apply-templates> 
      </xsl:for-each> 
     </products> 
    </xsl:template> 

    <xsl:template match="product"> 
     <xsl:param name="file"/> 
     <xsl:copy> 

      <xsl:apply-templates select="@*"/> 

      <xsl:if test="not(id)"> 
       <id><xsl:value-of select="@id"/></id> 
      </xsl:if> 

      <xsl:apply-templates select="node()"/> 

      <shopid><xsl:value-of select="$file"/></shopid> 

     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="category/@id 
     | product/@id"/> 

</xsl:stylesheet> 

当在问题提供paths.xml文件被应用时产生:

<products> 
    <product> 
     <id>189</id> 
     <title/> 
     <description/> 
     <price/> 
     <image/> 
     <url/> 
     <category/> 
     <shopid>shop1.xml</shopid> 
    </product> 
    <product> 
     <id>1418</id> 
     <title/> 
     <description/> 
     <price/> 
     <image/> 
     <url/> 
     <category/> 
     <shopid>shop1.xml</shopid> 
    </product> 
    <product> 
     <id>182</id> 
     <title/> 
     <description/> 
     <price/> 
     <image/> 
     <url/> 
     <category/> 
     <shopid>shop2.xml</shopid> 
    </product> 
    <product> 
     <id>118</id> 
     <title/> 
     <description/> 
     <price/> 
     <image/> 
     <url/> 
     <category/> 
     <shopid>shop2.xml</shopid> 
    </product> 
</products> 
+0

@尼古拉,我很抱歉'类别',我误解了你的问题。编辑的答案现在修复它。对于第二个问题,您的意思是说,您的某些Feed中有直接“产品”作为根元素?如果你扩大你的原始问题并添加这些新信息并尽可能清楚,那将会更好。我会尽快回复。 –

+0

@Nikolai,无论如何,我已经概括了用不同根元素管理其他提要的答案。 –

+0

对不起,我再次检查了我的一个Feed。我看到一些饲料不像'<产品ID = “123”>''但 123> ...'这就是为什么有一个额外的''下面的''对转换后的XML。所以如果我们有一个if子句,它检查是否有一个''然后创建''否则如果是''不创建它,但继续下一个元素。 – EnexoOnoma

相关问题