0

我正在尝试使用 XSL 将 xml 产品表转换为 CSV,但我无法在任何浏览器(Chrome、Safari 或 FF)中显示任何内容。我还将文件上传到我的实时服务器,但浏览器仍然没有呈现任何内容。

我看过其他类似的 SO 帖子(如何在浏览器中查看 xsl 输出?),并且已经更改了所提到的命名空间,但没有骰子。这里有什么明显的错误吗?

XML 示例:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="onix2csv.xsl"?>
<!DOCTYPE ONIXMessage SYSTEM "http://www.editeur.org/onix/2.1/02/reference/onix-international.dtd">
<ONIXMessage>
<Product>
    <RecordReference>9780002556132</RecordReference>
    <NotificationType></NotificationType>
    <ProductIdentifier>
        <ProductIDType>03</ProductIDType>
        <IDValue>9780002556132</IDValue>
        </ProductIdentifier>
        <ProductIdentifier>
        <ProductIDType>15</ProductIDType>
        <IDValue>9780002556132</IDValue>
    </ProductIdentifier>
    <ProductForm>BB</ProductForm>
    <ProductFormDetail>B402</ProductFormDetail>
    <Title>
        <TitleType>01</TitleType>
        <TitleText>Fish Rots From The Head</TitleText>
        <TitlePrefix></TitlePrefix>
        <TitleWithoutPrefix>Fish Rots From The Head</TitleWithoutPrefix>
    </Title>
    <Website>
        <WebsiteLink>http://www.allenandunwin.com/default.aspx?page=94&amp;book=9780002556132</WebsiteLink>
    </Website>
    <MediaFile>
        <MediaFileTypeCode>04</MediaFileTypeCode>
        <MediaFileLinkTypeCode>01</MediaFileLinkTypeCode>
        <MediaFileLink>http://www.allenandunwin.com/BookCovers/resized_9780002556132_224_297_FitSquare.jpg</MediaFileLink>
    </MediaFile>
    <Contributor>
        <SequenceNumber>001</SequenceNumber>
        <ContributorRole>A01</ContributorRole>
        <PersonName></PersonName>
        <PersonNameInverted>Garratt, Bob</PersonNameInverted>
    </Contributor>
    <EditionNumber>1</EditionNumber>
    <NumberOfPages>0</NumberOfPages>
    <BICMainSubject>KJ</BICMainSubject>
    <AudienceCode></AudienceCode>
    <OtherText>
        <TextTypeCode>01</TextTypeCode>
        <Text></Text>
    </OtherText>
    <Imprint>
        <ImprintName>Profile Business</ImprintName>
    </Imprint>
    <Publisher>
        <PublishingRole>01</PublishingRole>
        <PublisherName>Allen &amp; Unwin</PublisherName>
    </Publisher>
    <PublishingStatus>07</PublishingStatus>
    <PublicationDate>20021101</PublicationDate>
    <YearFirstPublished>2002</YearFirstPublished>
    <Measure>
        <MeasureTypeCode>01</MeasureTypeCode>
        <Measurement>0</Measurement>
        <MeasureUnitCode>mm</MeasureUnitCode>
    </Measure>
    <Measure>
        <MeasureTypeCode>02</MeasureTypeCode>
        <Measurement>0</Measurement>
        <MeasureUnitCode>mm</MeasureUnitCode>
    </Measure>
    <Measure>
        <MeasureTypeCode>08</MeasureTypeCode>
        <Measurement>0</Measurement>
        <MeasureUnitCode>gr</MeasureUnitCode>
    </Measure>
    <SupplyDetail>
        <SupplierName>United Book Distributors</SupplierName>
        <SupplierRole>02</SupplierRole>
        <ProductAvailability>40</ProductAvailability>
        <ExpectedShipDate></ExpectedShipDate>
        <Stock>
            <OnHand>No Stock</OnHand>
            <OnOrder>No</OnOrder>
        </Stock>
        <PackQuantity>1</PackQuantity>
        <Price>
            <PriceTypeCode>02</PriceTypeCode>
            <PriceAmount>0</PriceAmount>
        </Price>
    </SupplyDetail>
    <MarketRepresentation>
        <AgentName>Allen &amp; Unwin</AgentName>
        <AgentRole>07</AgentRole>
        <MarketCountry>AU</MarketCountry>
        <MarketPublishingStatus>07</MarketPublishingStatus>
        <MarketDate>
            <MarketDateRole>01</MarketDateRole>
            <Date>20021101</Date>
        </MarketDate>
    </MarketRepresentation>
</Product>

XSL 内容:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:template match="/"> 
        <xsl:apply-templates select="Product" mode="header"/> 
        <xsl:apply-templates select="Product" mode="data"/> 
    </xsl:template>

    <!-- HEADER ROW -->

    <xsl:template match="Product" mode="header">
        <xsl:text>RecordReference</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>NotificationType</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>ProductIdentifier</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>ProductForm</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>ProductFormDetail</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>Title</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>Website</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>MediaFile</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>Contributor</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>EditionNumber</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>NumberOfPages</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>BICMainSubject</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>AudienceCode</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>OtherText</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>Imprint</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>Publisher</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>PublishingStatus</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>PublicationDate</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>YearFirstPublished</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>Measure</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>Measure</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>Measure</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>SupplyDetail</xsl:text><xsl:text>,</xsl:text>
        <xsl:text>MarketRepresentation</xsl:text>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

    <!-- DATA RECORDS -->

    <xsl:template match="Product" mode="data">
        <xsl:apply-templates select="Product"/>
    </xsl:template>

    <xsl:template match="Product">
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="RecordReference"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="NotificationType"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="ProductIdentifier"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="ProductForm"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="ProductFormDetail"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="Title"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="Website"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="MediaFile"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="Contributor"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="EditionNumber"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="NumberOfPages"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="BICMainSubject"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="AudienceCode"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="OtherText"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="Imprint"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="Publisher"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="PublishingStatus"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="PublicationDate"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="singular_field"><xsl:with-param name="fieldname" select="YearFirstPublished"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="Measure"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="Measure"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="Measure"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="SupplyDetail"/></xsl:call-template> <xsl:value-of select="','"/>
        <xsl:call-template name="plural_field_text"><xsl:with-param name="fieldname" select="MarketRepresentation"/></xsl:call-template>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

    <!-- HELPER FUNCTIONS -->

    <xsl:template name="plural_field_text">
        <xsl:param name="fieldname"/>
        <xsl:call-template name="singular_field">
            <xsl:with-param name="fieldname">
                <xsl:for-each select="$fieldname/*">
                    <xsl:value-of select="."/>
                    <xsl:if test="position() != last()">
                        <xsl:text>;</xsl:text>
                    </xsl:if>
                </xsl:for-each>
            </xsl:with-param>
        </xsl:call-template>
    </xsl:template>      


    <xsl:template name="singular_field">
        <xsl:param name="fieldname"/>

        <xsl:variable name="linefeed">
            <xsl:text>&#10;</xsl:text>
        </xsl:variable>

        <xsl:choose>

            <xsl:when test="contains( $fieldname, '&quot;' )">
                <!-- Field contains a quote. We must enclose this field in quotes,
                    and we must escape each of the quotes in the field value.
                -->
                <xsl:text>"</xsl:text>

                <xsl:call-template name="escape_quotes">
                    <xsl:with-param name="string" select="$fieldname" />
                </xsl:call-template>

                <xsl:text>"</xsl:text>
            </xsl:when>

            <xsl:when test="contains( $fieldname, ',' ) or
                contains( $fieldname, $linefeed )" >
                <!-- Field contains a comma and/or a linefeed.
                    We must enclose this field in quotes.
                -->
                <xsl:text>"</xsl:text>
                <xsl:value-of select="$fieldname" />
                <xsl:text>"</xsl:text>
            </xsl:when>

            <xsl:otherwise>
                <!-- No need to enclose this field in quotes.
                -->
                <xsl:value-of select="$fieldname" />
            </xsl:otherwise>

        </xsl:choose>
    </xsl:template>

    <xsl:template name="escape_quotes">
        <xsl:param name="string" />

        <xsl:value-of select="substring-before( $string, '&quot;' )" />
        <xsl:text>""</xsl:text>

        <xsl:variable name="substring_after_first_quote"
            select="substring-after( $string, '&quot;' )" />

        <xsl:choose>

            <xsl:when test="not( contains( $substring_after_first_quote,
                '&quot;' ) )">
                <xsl:value-of select="$substring_after_first_quote" />
            </xsl:when>

            <xsl:otherwise>
                <!-- The substring after the first quote contains a quote.
                    So, we call ourself recursively to escape the quotes
                    in the substring after the first quote.
                -->

                <xsl:call-template name="escape_quotes">
                    <xsl:with-param name="string" select="$substring_after_first_quote"
                    />
                </xsl:call-template>
            </xsl:otherwise>

        </xsl:choose>

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

1 回答 1

1

这里有两个主要问题。首先是这个模板:

<xsl:template match="/"> 
    <xsl:apply-templates select="Product" mode="header"/> 
    <xsl:apply-templates select="Product" mode="data"/> 
</xsl:template>

Product不是根元素,因此这些apply-templates操作在空节点集上运行。您可以通过将此模板的第一行更改为:

<xsl:template match="/*"> 

同样在这里:

<xsl:template match="Product" mode="data">
  <xsl:apply-templates select="Product"/>
</xsl:template>

Product元素没有一个名为 的子元素Product,因此这apply-templates又是无作用的。您可以通过将第二行更改为:

  <xsl:apply-templates select="."/>

或者通过删除整个模板并添加mode="data"到下一个模板。

如果这两个问题都得到解决,XSLT 将生成 CSV。

于 2013-03-09T07:02:45.593 回答