XSLT 样式表中不需要的节点

Unwanted nodes in XSLT stylesheet

我不完全确定我的样式表目前的错误在哪里:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet exclude-result-prefixes="exsl xs"
extension-element-prefixes="exsl" version="2.0"
xmlns:exsl="http://exslt.org/common"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!--xsl:import-schema schema-location="ProductFeed5.6.xsd" / -->
    <xsl:output method="xml" indent="yes" encoding="UTF-8"
        byte-order-mark="no" omit-xml-declaration="no"
        xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6" />

    <xsl:strip-space elements="*" />

    <!-- Parameter to determine when using 'contoursbaby' or 'kolcraft' feed 
        values -->
    <xsl:param name="feedName" as="xs:string" />

    <!-- copy all nodes that do not match a given template -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/*">
        <xsl:choose>
            <xsl:when test="starts-with(name(), 'dataroot_')">
                <xsl:element name="Feed" namespace="http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6">
                    <xsl:attribute name="name" select="$feedName" />
                    <xsl:attribute name="incremental" select="'false'" />
                    <xsl:attribute name="extractDate"><xsl:value-of select='current-dateTime()' /></xsl:attribute>
                    <xsl:if test="not(empty($feedName))">
                        <xsl:choose>
                            <xsl:when test="$feedName eq 'kolcraft'">
                                <xsl:copy-of select="exsl:node-set(document('kolcraft-brands.xml'))" />
                                <xsl:copy-of select="exsl:node-set(document('kolcraft-categories.xml'))" />
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of select="document('contours-categories.xml')" />
                            </xsl:otherwise>
                        </xsl:choose>
                        <xsl:copy>
                            <xsl:apply-templates select="recordset" />
                        </xsl:copy>
                    </xsl:if>
                </xsl:element>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="recordset">
        <Products>
            <xsl:for-each select="row">
                <Product>
                    <xsl:attribute name="removed" select="'false'" />
                    <xsl:apply-templates select="@*|node()" />
                </Product>
            </xsl:for-each>
        </Products>
    </xsl:template>

    <xsl:template match="F1">
        <ExternalId><xsl:value-of select="." /></ExternalId>
    </xsl:template>

    <xsl:template match="F2">
        <UPCs>
            <UPC><xsl:value-of select="." /></UPC>
        </UPCs>
    </xsl:template>

    <xsl:template match="F3">
        <Name><xsl:value-of select="." /></Name>
    </xsl:template>

    <xsl:template match="F4">
        <Description><xsl:value-of select="." /></Description>
    </xsl:template>

    <xsl:template match="F5">
        <ProductPageUrl><xsl:value-of select="." /></ProductPageUrl>
    </xsl:template>

    <xsl:template match="F6">
        <ImageUrl><xsl:value-of select="." /></ImageUrl>
    </xsl:template>

    <xsl:template match="F7">
        <CategoryExternalId><xsl:value-of select="lower-case(normalize-space(replace(., '[/ ]', '-')))" /></CategoryExternalId>
    </xsl:template>

    <xsl:template match="fielddescription" />

</xsl:stylesheet>

我遇到了 2 个问题,我不确定它们为什么会发生: 1. <Brands> & <Categories> 在导入时得到一个空的命名空间 2. <dataroot_r00295> 继续作为根 <Feed>.

的第一个 child 出现

这是其使用的源文档类型的片段:

<?xml version="1.0" encoding="ISO-8859-1"?>
<dataroot_r00295>

  <fielddescription>
       <F1>ExternalID</F1>
       <F2>UPC</F2>
       <F3>Name</F3>
       <F4>Description</F4>
       <F5>ProductPageUrl</F5>
       <F6>ProductImageUrl</F6>
       <F7>CategoryExternalID</F7>
  </fielddescription>
   <recordset>
     <row>
            <F1>ED003-QCX</F1>     
            <F2>031878025147</F2>     
            <F3>Sealy Naturals-Cotton Crib Mattress Pad</F3>     
            <F4>Give baby plush comfort from natural cotton fibers with the innovative Sealy Naturals-Cotton Crib Mattress Pad.</F4>     
            <F5>http://www.kolcraft.com/sealy-naturals-cotton-crib-mattress-pad.html</F5>     
            <F6>http://www.kolcraft.com/media/catalog/product/e/d/ed003-qcx-1_1_4.jpg</F6>     
            <F7>Bedding/Pads</F7>     
     </row>
   </recordset>
</dataroot_r00295>

下面是它生成的片段:

<?xml version="1.0" encoding="UTF-8"?>
<Feed extractDate="2016-05-05T19:32:27.863-05:00"
        incremental="false"
        name="kolcraft"
        xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6">
        <Brands xmlns="">
            <Brand removed="false">
                <ExternalId>brands</ExternalId>
                <Name>Brands</Name>
                <!--BrandPageUrl>http://www.kolcraft.com/brands.html</BrandPageUrl -->
            </Brand>
        </Brands>
        <Categories xmlns="">
            <Category removed="false">
                <ExternalId>baby-products</ExternalId>
                <Name>Baby Products</Name>
                <CategoryPageUrl>http://www.kolcraft.com/baby-products.html</CategoryPageUrl>
            </Category>
        </Categories>
        <dataroot_r00295 xmlns="">
            <Products>
                <Product removed="false">
                    <ExternalId>ED003-QCX</ExternalId>
                    <UPCs>
                        <UPC>031878025147</UPC>
                    </UPCs>
                    <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>bedding-pads</CategoryExternalId>
                </Product>
            </Products>
        </dataroot_r00295>
</Feed>

谁能解释一下我的样式表出了什么问题?我被难住了。

另外:如果有任何其他更有效地使用模板的方法,请随时教我正确使用 XSLT 的方法。

一般来说,如果您想创建一个 XML 文档,其中的结果元素应该全部在某个命名空间中,那么正确且方便的方法是将该命名空间的命名空间声明放在xsl:stylesheet分别是xsl:transform样式表的根元素,即

<xsl:stylesheet
  exclude-result-prefixes="exsl xs"
  version="2.0"
  xmlns:exsl="http://exslt.org/common"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6">

这样,在不同模板中创建的所有结果元素都将位于该命名空间中,即使您需要在某个模板中更改它,您也可以在那里放置一个 xmlns=""

所以你应该摆脱出现的 xmlns="'' ,除非它们是由你复制的文档产生的。如果你从其他文档复制的那些元素不在命名空间中并且你希望它们在命名空间 http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6 中,那么你不能复制它们,而是必须使用例如转换它们<xsl:apply-templates select="document('foo.xml')/node()"/> 设置在命名空间中创建元素的模板,假设我之前的建议(在 xsl:stylesheet 上使用 xmlns="..."),

就足够了
<xsl:template match="*">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates select="@* | node()"/>
  </xsl:element>
</xsl:template>