2013-03-21 61 views
1

我有两个不同的XML文件重复:movies.xml和亚马逊商品广告API XMLXSLT - 转换两种不同的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> 

申请模板选择=“/电影/电影 - 从movies.xml载荷的5部电影列表,并将其显示为超链接

申请模板选择=” AWS:ItemLoo kupResponse/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标签。

如果我能以某种方式将这两个模板放到一个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); 

} 

movies.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> 

浏览器输出:

browser

+0

亚历克斯,同时显示XML的文件的一些片断...... – michi 2013-03-21 22:45:32

+0

我已经更新我的职务与XML文件 – Alex 2013-03-21 23:05:31

回答

1

我不能重现问题

随着您的XSLT代码(略微改变为访问“电影。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> 

,并具有提供的XML文档(文件” 的电影。 x:“)在本地目录”C:\ temp \ delete“中:

<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> 
+0

感谢您的回复,Dimitre。我已经加倍检查了所有内容,并且仍然得到了每个元素中包含head元素的html元素的副本。我认为我的PHP代码导致了这个问题,因为我正在创建并回显两个单独的xml文件。它们可能互相覆盖并导致所有html标记重复。我用我的浏览器显示的图像更新了我的帖子。 – Alex 2013-03-22 04:36:49

+0

@Alex,我已经对这个答案和我正在使用的所有11种不同的XSLT处理器进行了转换 - 它们都产生了相同的正确结果。如果您使用的是兼容的XSLT处理器,那么唯一的原因可能是至少有一个XML文档或转换本身与此答案中使用的不同。 – 2013-03-22 05:00:35

+1

@Alex,在使用'document()'添加对“movies.xml”的访问后,是否从PHP中删除了'echo $ proc-> transformToXML($ xml);'?您正在运行2个独立的转换。您只需在“$ response”XML上运行转换即可。 – 2013-03-22 05:06:10

1

看来XSLTProcessor不允许您将XML内容设置为参数(setParameter函数只接受一个字符串),因此您需要使用XSLT document函数来处理多个输入文档,如前所述herehere。您将需要保存您的从亚马逊在文件系统中的文件的响应,那么你的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> 

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

+0

谢谢你你的回复,Jollymorphic。我已经应用您的解决方案,但不幸的是,我仍然得到重复的“电影列表”H2标记。也许我没有正确解释我的问题,但我只想显示“电影列表”标题文本,然后列出5个超链接电影标题,然后显示下面的“黑暗骑士亚马逊电影标题”。我不想在5部电影标题和亚马逊标题之间有任何关系,我只是试图在我的电影列表页面中包含亚马逊api,并看看它将如何工作。我想要的只是将其显示在一个没有“电影列表”标题的HTML标签中。 – Alex 2013-03-22 01:29:55