1

我有两个不同的 XML 文件:movies.xml 和亚马逊产品广告 API XML

这是我转换两个 XML 文件的 XSLT 文件:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:aws="http://webservices.amazon.com/AWSECommerceService/2011-08-01"
exclude-result-prefixes="aws">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

<xsl:template match="/">
    <xsl:element name="html">
        <xsl:element name="head">
            <xsl:element name="h2">Movies list</xsl:element>
        </xsl:element>
        <xsl:element name="body">
            <xsl:apply-templates select="/movies/movie"/>
            <xsl:apply-templates select="aws:ItemLookupResponse/aws:Items/aws:Item/aws:ItemAttributes/aws:Title"/>
        </xsl:element>
    </xsl:element>
</xsl:template>

<xsl:template match="movie">
    <xsl:element name="a">
        <xsl:attribute name="href">movie_details.php?movieID=<xsl:value-of select="@movieID"/></xsl:attribute>
        <xsl:value-of select="title"/>
    </xsl:element>
    <xsl:element name="br" />
</xsl:template>

<xsl:template match="aws:Title">
    <xsl:element name="h2">Amazon Movie 1</xsl:element>
    <xsl:value-of select="." />
</xsl:template>

</xsl:stylesheet>

apply-templates select="/movies/movie - 从 movies.xml 加载 5 个电影标题的列表并将它们显示为超链接。

apply-templates select="aws:ItemLookupResponse/aws:Items/aws:Item/aws:ItemAttributes/aws:Title" - 从 Amazon API xml 文件加载电影标题并将其显示为纯文本。

这是我的 HTML 输出:

<html>
  <head>
    <h2>Movies list</h2>
  </head>
  <body>
    <a href="movie_details.php?movieID=1">The Dark Knight Rises</a>
    <br/>
    <a href="movie_details.php?movieID=2">Lawless</a>
    <br/>
    <a href="movie_details.php?movieID=3">Inception</a>
    <br/>
    <a href="movie_details.php?movieID=4">Looper</a>
    <br/>
    <a href="movie_details.php?movieID=5">Django Unchained</a>
    <br/>
  </body>
</html>
<html>
  <head>
    <h2>Movies list</h2>
  </head>
  <body><h2>Amazon Movie 1</h2>Dark Knight Rises [Blu-ray] [2012] [US Import]</body>
</html>

如您所见,这两个模板显示在单独的 HTML 标记中,这导致两个模板的 Head 元素“电影列表”显示两次。

如果我能以某种方式将这两个模板放入一个 HTML 元素中,那么就不会重复任何内容。我尝试了几种方法,但还没有成功。

这是我的 PHP 文件,它创建了两个 XML 文件和一个 XSLT 样式表。它还会生成亚马逊产品的签名 URL。

include('aws_signed_request.php');

$public_key = 'XXXXXXXXXXXXXXXXXXXXXX';
$private_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$associate_tag = 'xxxxxxxxxxxxxxxxxxxxxxx';

// generate signed URL
$request = aws_signed_request('co.uk', array(
        'Operation' => 'ItemLookup',
        'ItemId' => 'B004LWZWGK',
        'ResponseGroup' => 'Small'), $public_key, $private_key, $associate_tag);

// do request (you could also use curl etc.)
$response = @file_get_contents($request);
if ($response === FALSE) {
    echo "Request failed.\n";
} else {

    // parse XML
    $xml = new DOMDocument();
    $xml->load('movies.xml');

    $xml2 = new DOMDocument();
    $xml2->loadXML($response);

    $xsl = new DOMDocument;
    $xsl->load('movies_list.xsl');

    $proc = new XSLTProcessor();
    $proc->importStyleSheet($xsl);

    echo $proc->transformToXML($xml);
    echo $proc->transformToXML($xml2);

}

电影.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="index.xsl"?>
<movies
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="movies.xsd">

<movie movieID="1">
    <title>The Dark Knight Rises</title>
</movie>

<movie movieID="2">
    <title>Lawless</title>
</movie>

<movie movieID="3">
    <title>Inception</title>
</movie>

<movie movieID="4">
    <title>Looper</title>
</movie>

<movie movieID="5">
    <title>Django Unchained</title>
</movie>
</movies>

亚马逊产品广告 API XML

<ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
   <OperationRequest>
       <HTTPHeaders>
          <Header Name="UserAgent" Value="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22"/>
       </HTTPHeaders>
       <RequestId>a1138e89-4335-4650-80f2-641e3c58b623</RequestId>
       <Arguments>
    <Argument Name="Operation" Value="ItemLookup"/>
    <Argument Name="Service" Value="AWSECommerceService"/>
    <Argument Name="Signature" Value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"/>
    <Argument Name="AssociateTag" Value="xxxxxxxxxxxxxx"/>
    <Argument Name="Version" Value="2011-08-01"/>
    <Argument Name="ItemId" Value="B004LWZWGK"/>
    <Argument Name="AWSAccessKeyId" Value="xxxxxxxxxxxxxxxxxxxx"/>
    <Argument Name="Timestamp" Value="2013-03-21T13:56:55.000Z"/>
    <Argument Name="ResponseGroup" Value="Small"/>
       </Arguments>
       <RequestProcessingTime>0.0189320000000000</RequestProcessingTime>
       </OperationRequest>
    <Items>
      <Item>
         <ItemAttributes>
           <Title>
            The Dark Knight Rises (Blu-ray/DVD Combo+UltraViolet Digital Copy)
           </Title>
         </ItemAttributes>
      </Item>
    </Items>
</ItemLookupResponse>

浏览器输出:

浏览器.

4

2 回答 2

1

XSLTProcessor 似乎不允许您将 XML 内容设置为参数(setParameter 函数只接受一个字符串),因此您需要使用 XSLTdocument函数来处理多个输入文档,如此处和此处所讨论。您需要将来自 Amazon 的响应保存为文件系统中的文件,然后您的 XSLT 可能看起来像这样(我在其中简化了您的文件名):

<xsl:variable name="amazon" select="document('amazon.xml')"/>

<xsl:template match="/">
    <html>
        <body>
            <h2>Movies List</h2>
            <xsl:apply-templates select="movies/movie" />
            <h2>
                <xsl:value-of select="normalize-space($amazon/aws:ItemLookupResponse/aws:Items/aws:Item/aws:ItemAttributes/aws:Title)"/>
            </h2>
        </body>
    </html>
</xsl:template>

<xsl:template match="movie">
    <a>
        <xsl:attribute name="href">movie_details.php?movieID=<xsl:value-of select="@movieID"/></xsl:attribute>
        <xsl:value-of select="title"/>
    </a>
    <br/>
</xsl:template>

编辑:根据您对我的原始答案的评论修改了代码,并删除了关于“多对一”问题的语言。

于 2013-03-22T00:56:13.363 回答
1

我无法重现问题

使用您的 XSLT 代码(稍微更改为通过调用函数访问“movies.xml” document()):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:aws="http://webservices.amazon.com/AWSECommerceService/2011-08-01"
exclude-result-prefixes="aws">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

<xsl:variable name="vMoviesDoc" select=
 "document('file:///c:/temp/delete/movies.xml')"/>

<xsl:template match="/">
    <xsl:element name="html">
        <xsl:element name="head">
            <xsl:element name="h2">Movies list</xsl:element>
        </xsl:element>
        <xsl:element name="body">
            <xsl:apply-templates select="$vMoviesDoc/movies/movie"/>
            <xsl:apply-templates select="aws:ItemLookupResponse/aws:Items/aws:Item/aws:ItemAttributes/aws:Title"/>
        </xsl:element>
    </xsl:element>
</xsl:template>

<xsl:template match="movie">
    <xsl:element name="a">
        <xsl:attribute name="href">movie_details.php?movieID=<xsl:value-of select="@movieID"/></xsl:attribute>
        <xsl:value-of select="title"/>
    </xsl:element>
    <xsl:element name="br" />
</xsl:template>

<xsl:template match="aws:Title">
    <xsl:element name="h2">Amazon Movie 1</xsl:element>
    <xsl:value-of select="." />
</xsl:template>

</xsl:stylesheet>

应用于提供的亚马逊产品广告 API XML文档时:

<ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
   <OperationRequest>
       <HTTPHeaders>
          <Header Name="UserAgent" Value="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22"/>
       </HTTPHeaders>
       <RequestId>a1138e89-4335-4650-80f2-641e3c58b623</RequestId>
       <Arguments>
    <Argument Name="Operation" Value="ItemLookup"/>
    <Argument Name="Service" Value="AWSECommerceService"/>
    <Argument Name="Signature" Value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"/>
    <Argument Name="AssociateTag" Value="xxxxxxxxxxxxxx"/>
    <Argument Name="Version" Value="2011-08-01"/>
    <Argument Name="ItemId" Value="B004LWZWGK"/>
    <Argument Name="AWSAccessKeyId" Value="xxxxxxxxxxxxxxxxxxxx"/>
    <Argument Name="Timestamp" Value="2013-03-21T13:56:55.000Z"/>
    <Argument Name="ResponseGroup" Value="Small"/>
       </Arguments>
       <RequestProcessingTime>0.0189320000000000</RequestProcessingTime>
       </OperationRequest>
    <Items>
      <Item>
         <ItemAttributes>
           <Title>
            The Dark Knight Rises (Blu-ray/DVD Combo+UltraViolet Digital Copy)
           </Title>
         </ItemAttributes>
      </Item>
    </Items>
</ItemLookupResponse>

并在本地目录“C:\temp\delete”中拥有提供的 XML 文档(文件“movies.xml”):

<movies xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="movies.xsd">
    <movie movieID="1">
        <title>The Dark Knight Rises</title>
    </movie>
    <movie movieID="2">
        <title>Lawless</title>
    </movie>
    <movie movieID="3">
        <title>Inception</title>
    </movie>
    <movie movieID="4">
        <title>Looper</title>
    </movie>
    <movie movieID="5">
        <title>Django Unchained</title>
    </movie>
</movies>

转换产生以下结果,其中没有重复head

<html>
   <head>
      <h2>Movies list</h2>
   </head>
   <body>
      <a href="movie_details.php?movieID=1">The Dark Knight Rises</a>
      <br/>
      <a href="movie_details.php?movieID=2">Lawless</a>
      <br/>
      <a href="movie_details.php?movieID=3">Inception</a>
      <br/>
      <a href="movie_details.php?movieID=4">Looper</a>
      <br/>
      <a href="movie_details.php?movieID=5">Django Unchained</a>
      <br/>
      <h2>Amazon Movie 1</h2>
            The Dark Knight Rises (Blu-ray/DVD Combo+UltraViolet Digital Copy)
           </body>
</html>
于 2013-03-22T03:13:17.487 回答