2016-11-25 24 views
0

我對電影的XML文件看起來像這樣(短版)XSLT:選擇一個idref並查找更正。元素

<movie id="movie_tt0004994"> 
     <title>Bound on the Wheel </title> 
     <stars idref="star_nm0933368 star_nm0913085 star_nm0151606"/> 
    </movie> 
    <star id="star_nm0933368"> 
     <name>Elsie Jane Wilson</name> 
    </star> 

我想這個XML轉換成HTML,使用XSLT。該html應該是一個表格,其中第一列的電影名稱和下面三列中的星號NAMES(最多3個)。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
<xsl:template match="/"> 
<html> 
<body> 
<h2>movie list</h2> 
<table border="1"> 
<th>Title</th> 
<th colspan="3">Stars</th> 
</tr> 
<xsl:for-each select="IMDb/movie"> 
<tr> 
<td><xsl:value-of select="title" /></td> 
<xsl:for-each select="stars/@idref"> 
<xsl:variable name="curr_ref" select="."/> 
<td><xsl:value-of select="//IMDb/star[@id=$curr_ref]/name"/></td> 
</xsl:for-each>  
</tr> 
</xsl:for-each>  
</table> 
</font> 
</body> 
</html> 
</xsl:template> 
</xsl:transform> 

問題是,它只適用於有一顆星的電影。如果星星中有多個星號(例如我的xml的給定部分中的電影),那麼表格中的相應列保持空白。我認爲這是因爲該行然後使curr_ref一個長串的所有idrefs而不是三個獨立的。我應該怎麼做呢?

+0

你是否限於XSLT 1.0 ?或者你可以使用XSLT 2.0 ''等對於$ ref,在標記大小中的​​...'? –

+0

當然,首選的解決方案是更改XML模式,因爲爲了存儲多個項目,應該使用**節點**集合(而不是使用字符級別分隔符存儲它們)。 –

+0

@LittleSanti,模式語言的類型爲https://www.w3.org/TR/xmlschema-2/#IDREFS,它是一系列空間分離的IDREF值,因此假設模式呈現良好。只有支持模式的XSLT 2.0不像普通的XSLT 2.0那樣受到廣泛支持,例如Saxon 9只支持支持模式的XSLT 2.0或3.0。 –

回答

2

假設XSLT 2.0可以使用

<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:key name="star" match="star" use="@id"/> 

<xsl:template match="/"> 
<html> 
<body> 
<h2>movie list</h2> 
<table border="1"> 
<tr> 
<th>Title</th> 
<th colspan="3">Stars</th> 
</tr> 
<xsl:for-each select="IMDb/movie"> 
<tr> 
<td><xsl:value-of select="title" /></td> 
<xsl:for-each select="for $ref in tokenize(stars/@idref, '\s+') return key('star', $ref)"> 
<td><xsl:value-of select="name"/></td> 
</xsl:for-each>  
</tr> 
</xsl:for-each>  
</table> 
</body> 
</html> 
</xsl:template> 

</xsl:transform> 

假設XSLT 1.0(或更高版本)和DTD支持可以使用

<!DOCTYPE IDMb [ 
<!ATTLIST star 
    id ID #REQUIRED> 
<!ATTLIST stars 
    idref IDREFS #REQUIRED> 
]> 

<IMDb> 
<movie id="movie_tt0004994"> 
     <title>Bound on the Wheel </title> 
     <stars idref="star_nm0933368 star_nm0913085 star_nm0151606"/> 
    </movie> 
    <star id="star_nm0933368"> 
     <name>Elsie Jane Wilson</name> 
    </star> 
</IMDb> 

<xsl:template match="/"> 
<html> 
<body> 
<h2>movie list</h2> 
<table border="1"> 
<tr> 
<th>Title</th> 
<th colspan="3">Stars</th> 
</tr> 
<xsl:for-each select="IMDb/movie"> 
<tr> 
<td><xsl:value-of select="title" /></td> 
<xsl:for-each select="id(stars/@idref)"> 
<td><xsl:value-of select="name"/></td> 
</xsl:for-each>  
</tr> 
</xsl:for-each>  
</table> 
</body> 
</html> 
</xsl:template> 
相關問題