2016-04-29 32 views
0

我正在使用XSLT样式表将CSV转换为XML,但我也需要在CSV转换后使用几个模板转换XML。下面是应该换任何<UPC>031878025147</UPC>节点作为样式表的一部分:将节点包装在新的父节点中?

<UPCs> <UPC>031878025147</UPC> <UPCs>

这里是一个本应与<UPCs>包裹<UPC>节点样式表的代码片段:

<?xml version='1.0' encoding='UTF-8'?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fn="fn" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    version="2.0" exclude-result-prefixes="xs fn"> 
    <xsl:output method="xml" indent="yes" encoding="UTF-8" /> 

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

    <xsl:template match="//UPC[preceding-sibling::ExternalId]"> 
     <xsl:variable select="." name="curElem" /> 
     <xsl:for-each select="."> 
     <UPCs> 
      <xsl:copy-of select="$curElem" /> 
     </UPCs> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

这里有一个它将解析XML的片段:

<Feed name="example" incremental="false" extractDate="2016-04-28T13:42:09-05:00" xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/14.5"> 
    <Brands> 
    <Brand removed="false"> 
     <ExternalId>brands</ExternalId> 
     <Name>Brands</Name> 
     <!--BrandPageUrl>http://www.kolcraft.com/brands.html</BrandPageUrl--> 
    </Brand> 
    <!-- ... --> 
    </Brands> 
    <Categories> 
    <Category removed="false"> 
     <ExternalId>baby-products</ExternalId> 
     <Name>Baby Products</Name> 
     <CategoryPageUrl>http://www.kolcraft.com/baby-products.html</CategoryPageUrl> 
    </Category> 
    </Categories> 
    <Products> 
    <Product> 
     <ExternalId>ED003-QCX</ExternalId> 
     <UPC>031878025147</UPC> 
     <Name>Sealy Naturals-Cotton Crib Mattress Pad</Name> 
     <Description>Give baby plush comfort from natural cotton fibers with the innovative Sealy Naturals-Cotton Crib Mattress Pad.</Description> 
     <ProductPageUrl>http://www.kolcraft.com/sealy-naturals-cotton-crib-mattress-pad.html</ProductPageUrl> 
     <ImageUrl>http://www.kolcraft.com/media/catalog/product/e/d/ed003-qcx-1_1_4.jpg</ImageUrl> 
     <CategoryExternalId>crib-bedding</CategoryExternalId> 
    </Product> 
    <!-- ... --> 
    </Products> 
</Feed> 

但是,t他似乎没有捕获到父节点<UPCs>之外的任何<UPC>节点。我在这里错过了什么?欢迎任何帮助。

+1

你可以添加一个你应该处理的xml片段吗? – bknights

+0

刚刚添加它。 :) –

回答

1

这是因为你在你的XML

<Feed ... xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/14.5"> 

有一个默认的命名空间声明这意味着Feed元素以及所有子元素都在该命名空间。然而,你的XSLT没有考虑到这个命名空间,所以这看起来与没有命名空间的元素UPC匹配,这不是一回事。

在使用XSLT 2.0时,实际上可以使用xpath-default-namespace为xpath表达式指定默认命名空间,如模板匹配。您还需要为XSLT定义默认命名空间,以确保新的UPCs在相同的命名空间中获取输出。

试试这个XSLT

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fn="fn" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xpath-default-namespace="http://www.bazaarvoice.com/xs/PRR/ProductFeed/14.5" 
    xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/14.5" 
    version="2.0" exclude-result-prefixes="xs fn"> 
    <xsl:output method="xml" indent="yes" encoding="UTF-8" /> 

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

    <xsl:template match="UPC[preceding-sibling::ExternalId]"> 
     <UPCs> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
     </UPCs> 
    </xsl:template> 
</xsl:stylesheet> 

注意我还简化了模板,因为我无法看到一个新的变量来的for-each语句。

编辑:在回应评论时,请注意,在模板匹配开始时不需要使用双斜杠//

+0

:)这个伎俩!谢谢! –

+0

是的,你是对的。在这种情况下,双斜杠是不必要的,所以我已经删除它。谢谢! –

相关问题