使用XSLT转换含同名嵌套元素的XML至HTML遇阻求助
我明白你现在卡在XSLT处理重复<marcEntry>元素这里了——这种同名但属性、内容不同的嵌套元素确实容易让人头疼。我来给你几个实用的处理思路,结合你的XML示例来拆解:
先把你的XML片段整理出来方便参考:
<catalog> <catalogKey>77971</catalogKey> <yearOfPublication>1999</yearOfPublication> <marc> <marcEntry tag="035" label="Local system #" ind=" ">77971</marcEntry> <marcEntry tag="035" label="Local system #" ind=" ">DIT87496</marcEntry> <!-- 其他marcEntry元素 --> </marc> </catalog>
方案1:遍历所有marcEntry,统一展示
如果只是想把所有<marcEntry>都列出来,不管属性是否相同,用<xsl:for-each>循环就能轻松搞定。示例XSLT代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h1>Catalog Details</h1> <p>Catalog Key: <xsl:value-of select="catalog/catalogKey"/></p> <p>Year: <xsl:value-of select="catalog/yearOfPublication"/></p> <h2>Marc Entries</h2> <ul> <xsl:for-each select="catalog/marc/marcEntry"> <li> <strong>Tag:</strong> <xsl:value-of select="@tag"/><br/> <strong>Label:</strong> <xsl:value-of select="@label"/><br/> <strong>Value:</strong> <xsl:value-of select="."/> </li> </xsl:for-each> </ul> </body> </html> </xsl:template> </xsl:stylesheet>
这个代码会把每个marcEntry转换成列表项,清晰展示它的tag、label和内容,不管属性是不是重复的。
方案2:按属性分组展示(比如按tag或label)
如果想把相同tag或label的marcEntry归为一组展示,分两种情况处理:
XSLT 2.0及以上版本(推荐)
用<xsl:for-each-group>直接分组,代码更简洁:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h1>Catalog Details</h1> <p>Catalog Key: <xsl:value-of select="catalog/catalogKey"/></p> <p>Year: <xsl:value-of select="catalog/yearOfPublication"/></p> <h2>Marc Entries Grouped by Tag</h2> <xsl:for-each-group select="catalog/marc/marcEntry" group-by="@tag"> <h3>Tag: <xsl:value-of select="current-grouping-key()"/></h3> <ul> <xsl:for-each select="current-group()"> <li> <strong>Label:</strong> <xsl:value-of select="@label"/><br/> <strong>Value:</strong> <xsl:value-of select="."/> </li> </xsl:for-each> </ul> </xsl:for-each-group> </body> </html> </xsl:template> </xsl:stylesheet>
XSLT 1.0版本(兼容旧环境)
用Muenchian分组法,先定义key再分组:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 定义key,按tag分组 --> <xsl:key name="marcByTag" match="marcEntry" use="@tag"/> <xsl:template match="/"> <html> <body> <h1>Catalog Details</h1> <p>Catalog Key: <xsl:value-of select="catalog/catalogKey"/></p> <p>Year: <xsl:value-of select="catalog/yearOfPublication"/></p> <h2>Marc Entries Grouped by Tag</h2> <!-- 只选每个tag的第一个元素作为分组起点 --> <xsl:for-each select="catalog/marc/marcEntry[count(. | key('marcByTag', @tag)[1]) = 1]"> <xsl:sort select="@tag"/> <h3>Tag: <xsl:value-of select="@tag"/></h3> <ul> <!-- 遍历当前tag下的所有marcEntry --> <xsl:for-each select="key('marcByTag', @tag)"> <li> <strong>Label:</strong> <xsl:value-of select="@label"/><br/> <strong>Value:</strong> <xsl:value-of select="."/> </li> </xsl:for-each> </ul> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>
方案3:筛选特定属性的marcEntry
如果只需要展示某个特定tag或label的marcEntry,比如只取tag="035"的,直接用属性筛选就行:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h1>Catalog Details</h1> <p>Catalog Key: <xsl:value-of select="catalog/catalogKey"/></p> <p>Year: <xsl:value-of select="catalog/yearOfPublication"/></p> <h2>Local System IDs (Tag 035)</h2> <ul> <xsl:for-each select="catalog/marc/marcEntry[@tag='035']"> <li><xsl:value-of select="."/></li> </xsl:for-each> </ul> </body> </html> </xsl:template> </xsl:stylesheet>
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

