通过使用xslt将xml转换为xml来寻找合并多个xml文件的正确方法

时间:2013-01-08 15:12:39

标签: xml xslt xslt-1.0

我在学习XSLT时遇到困难,并且遇到了一个挑战,我最终需要对100多种产品进行过滤和排序,我一次只能从网络服务中检索20种产品。我已经能够成功地拉动这些产品并操纵它们,但仅限于它们的原始批次,而不是它们是一个列表。所以我尝试将单独的文件转换为如下所示。

合并多个文件,如下所示:

A.XML

<?xml version="1.0" encoding="UTF-8"?>
<productSearchResponse>
    <products>
        <product>
            <code>A1</code>
            <item> SAUVIGNON RESERVA</item>
            <country>Spain</country>
            <region>Penedes</region>
            <category>Red</category>
            <style>Full-bodied</style>
        </product>
        <product>
            <code>A2</code>
            <item>RESERVE RIESLING</item>
            <country>France</country>
            <region>Alsace</region>
            <category>White</category>
            <style>Aromatic</style>
        </product>
        <product>
            <code>A3</code>
            <item>GAMAY</item>
            <country>Canada</country>
            <region>Ontario</region>
            <category>Red</category>
            <style>Medium-bodied</style>
        </product>
    </products>
</productSearchResponse>

......用这个:

B.XML

<?xml version="1.0" encoding="UTF-8"?>
<productSearchResponse>
    <products>
        <product>
            <code>B1</code>
            <item>BOURGOGNE CHARDONNAY</item>
            <country>France</country>
            <region>Burgundy</region>
            <category>White</category>
            <style>Light</style>
        </product>
        <product>
            <code>B2</code>
            <item>ONTARIO RIESLING II</item>
            <country>Canada</country>
            <region>Ontario</region>
            <category>White</category>
            <style>Off-dry</style>
        </product>
        <product>
            <code>B3</code>
            <item>WEST COAST CAB SAUV</item>
            <country>USA</country>
            <region>California</region>
            <category>Red</category>
            <style>Full-bodied</style>
        </product>
    </products>
</productSearchResponse>

...获取一个看起来像这样的新xml文件: all.xml

<?xml version="1.0" encoding="UTF-8"?>
<productSearchResponse>
    <products>
        <product>
            <code>A1</code>
            <item> SAUVIGNON RESERVA</item>
            <country>Spain</country>
            <region>Penedes</region>
            <category>Red</category>
            <style>Full-bodied</style>
        </product>
        <product>
            <code>A2</code>
            <item>RESERVE RIESLING</item>
            <country>France</country>
            <region>Alsace</region>
            <category>White</category>
            <style>Aromatic</style>
        </product>
        <product>
            <code>A3</code>
            <item>GAMAY</item>
            <country>Canada</country>
            <region>Ontario</region>
            <category>Red</category>
            <style>Medium-bodied</style>
        </product>
        <product>
            <code>B1</code>
            <item>BOURGOGNE CHARDONNAY</item>
            <country>France</country>
            <region>Burgundy</region>
            <category>White</category>
            <style>Light</style>
        </product>
        <product>
            <code>B2</code>
            <item>ONTARIO RIESLING II</item>
            <country>Canada</country>
            <region>Ontario</region>
            <category>White</category>
            <style>Off-dry</style>
        </product>
        <product>
            <code>B3</code>
            <item>WEST COAST CAB SAUV</item>
            <country>USA</country>
            <region>California</region>
            <category>Red</category>
            <style>Full-bodied</style>
        </product>
    </products>
</productSearchResponse>

我尝试过使用此

ABC.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ABC.xsl"?>
<essentials>
    <webservice filename="A.xml"/>
    <webservice filename="B.xml"/>
    <!-- etc -->
</essentials>

用这个

ABC.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"  indent="yes"/>
    <xsl:template match="/">
        <output>
            <xsl:for-each select="/essentials/webservice">
                <xsl:for-each select="document(@filename)/productSearchResponse/products/product">
                    <product>
                        <code>
                            <xsl:value-of select="code"/>
                        </code>
                        <item>
                            <xsl:value-of select="item"/>
                        </item> 
                        <country>
                            <xsl:value-of select="country"/>
                        </country>  
                        <region>
                            <xsl:value-of select="region"/>
                        </region>   
                        <category>
                            <xsl:value-of select="category"/>
                        </category>                 
                        <style>
                            <xsl:value-of select="style"/>
                        </style>
                    </product>              
                </xsl:for-each> 
            </xsl:for-each>
        </output>
    </xsl:template>
</xsl:stylesheet>

....但最后在浏览器中结束:

A1 SAUVIGNON RESERVASpainPenedesRedFull-bodiedA2RESERVE RIESLINGFranceAlsaceWhiteAromaticA3GAMAYCanadaOntarioRedMedium-bodiedB1BOURGOGNE CHARDONNAYFranceBurgundyWhiteLightB2ONTARIO雷司令IICanadaOntarioWhiteOff-dryB3WEST海岸CAB SAUVUSACaliforniaRedFull-bodiedC1BURGUNDY PINOT NOIRFranceBurgundyRedMedium-bodiedC2CALIFORNIAN WHITEUSACaliforniaWhiteOff-dryC3CANADIAN REDCanadaOntarioRedFull健全

Firebug在幕后显示结果是所需的xml。我感到难过的地方是:我怎样才能将结果变成我可以使用的形式,我可以将其视为常规xml并进行进一步的转换?我找到了正确的方法,还是我在错误的树上咆哮,这使得它太复杂了?

1 个答案:

答案 0 :(得分:1)

直接在浏览器中进行XML到XML的转换通常不是使用这种转换形式的好方法,大多数浏览器或至少Mozilla浏览器都假设您的目标格式类似于浏览器知道要呈现的XHTML或SVG。在你的情况下它不是,因此所有Firefox都会显示文本节点的无格式内容。

当然,您的代码可以简化:

<xsl:template match="/">
  <productSearchResponse>
    <products>
      <xsl:copy-of select="document(essentials/webservice/@filename)//product"/>
    </products>
  </productSearchResponse>
</xsl:template>

然而,这不会改变Firefox / Mozilla中的渲染。