如何用XSLT将特定类的未知XML元素格式化为HTML?
所以,我有我的应用程序是这样生成的XML文档:如何用XSLT将特定类的未知XML元素格式化为HTML?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AddressBook>
<?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?>
<AddressBook>
<Item>
<UserGeneratedElementName1 class="info">Whatever blah blah</UserGeneratedElementName1>
<UserGeneratedElementName2 class="info">Whatever blah blah</UserGeneratedElementName2>
</Item>
<Item>
<UserGeneratedElementName3 class="info">Whatever blah blah</UserGeneratedElementName3>
</Item>
...
...
Other Items with user-generated elements with user-generated content...
</AddressBook>
而且我希望把它变成一个类似的HTML文档:
<html>
<head>
<title>AddressBook</title>
</head>
<body>
<div class="root">
<div class="item">
<b>UserGeneratedElementName1:</b> Whatever blah blah
<b>UserGeneratedElementName2:</b> Whatever blah blah
</div>
<div class="item">
<b>UserGeneratedElementName3:</b> Whatever blah blah
</div>
...
...
Other transformed items...
</div>
</body>
</html>
我试图让一抓的XSLT语法,但是所有的指南要么太模糊,不能帮助我解决这个问题,要么太深入。另外XSLT语法看起来很混乱。 在此先感谢。
在这个问题看看这里
Is there an XSLT name-of element?
您可以使用
<xsl:value-of select ="name(.)"/>
或
<xsl:value-of select ="local-name()"/>
得到一个节点的名称,这取决于你想要包含完整的前缀名称,或仅包含本地部分。
您应该可以将这些与xsl:for-each块一起拼凑起来,以迭代项目的前三个级别并生成您正在寻找的HTML。
像这样的东西可以适用于固定数量的水平。
<xsl:for-each select="*">
<html>
<head>
<title><xsl:value-of select="local-name()" /></title>
</head>
<body>
<div class="root">
<xsl:for-each select="*">
<div>
<xsl:attribute name="class">
<xsl:value-of select="local-name()" />
</xsl:attribute>
<xsl:for-each select="*">
<b><xsl:value-of select="local-name()" />:</b> <xsl:value-of select="." />
</xsl:for-each>
</div>
</xsl:for-each>
</div>
</body>
</html>
</xsl:for-each>
一个更通用的方法会看起来更象:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" indent="yes" version="4.0"/>
<xsl:template match="/">
<xsl:for-each select="*">
<html>
<head>
<title><xsl:value-of select="local-name()" /></title>
</head>
<body>
<div class="root">
<xsl:call-template name="recurseElement">
<xsl:with-param name="element" select="." />
</xsl:call-template>
</div>
</body>
</html>
</xsl:for-each>
</xsl:template>
<xsl:template name="recurseElement">
<xsl:param name="element" />
<xsl:for-each select="$element/*">
<xsl:choose>
<xsl:when test="count(child::*)>0">
<div>
<xsl:attribute name="class">
<xsl:value-of select="local-name()" />
</xsl:attribute>
<xsl:call-template name="recurseElement">
<xsl:with-param name="element" select="." />
</xsl:call-template>
</div>
</xsl:when>
<xsl:otherwise>
<b><xsl:value-of select="local-name()" />:</b> <xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
请原谅我的无知,但是代码不会创建多个HTML文档,或者更确切地说,是不是它会在html文档中创建多个html元素?当然,这会使其无效,因为html文档可能只有一个html元素。 – FNj 2011-05-27 20:05:36
如果源XML文档有多个根节点(这将是无效的XML),则底部的xslt只会生成多个HTML文档。在这种情况下,第一个循环可能已被替换为'xsl:for-each select =“/”',如果这样做更有意义。我特意处理根目录并将其包装在HTML中的原因是因为该示例显示了用作HTML文档的根元素的名称
这个完整的XSLT转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="AddressBook">
<html>
<head>
<title>AddressBook</title>
</head>
<body>
<div class="root">
<xsl:apply-templates/>
</div>
</body>
</html>
</xsl:template>
<xsl:template match="Item">
<div class="item"><xsl:apply-templates/></div>
</xsl:template>
<xsl:template match="Item/*">
<b><xsl:value-of select="name()"/>:</b> <xsl:text/>
<xsl:value-of select="concat(.,'
 ')"/>
</xsl:template>
</xsl:stylesheet>
时所提供的XML文档应用:
<AddressBook>
<Item>
<UserGeneratedElementName1 class="info">Whatever blah blah</UserGeneratedElementName1>
<UserGeneratedElementName2 class="info">Whatever blah blah</UserGeneratedElementName2>
</Item>
<Item>
<UserGeneratedElementName3 class="info">Whatever blah blah</UserGeneratedElementName3>
</Item> ... ... Other Items with user-generated elements with user-generated content...
</AddressBook>
产生想要的,正确的结果:
<html>
<head>
<title>AddressBook</title>
</head>
<body>
<div class="root">
<div class="item">
<b>UserGeneratedElementName1:</b>Whatever blah blah
<b>UserGeneratedElementName2:</b>Whatever blah blah
</div>
<div class="item">
<b>UserGeneratedElementName3:</b>Whatever blah blah
</div> ... ... Other Items with user-generated elements with user-generated content...
</div>
</body>
</html>
说明:
Templates matching任何
Item
元素和Item
元素的任何元素的孩子。使用标准XPath
name()
函数。
这条线究竟做了什么? '
@FNj:xsl:select-value-'concat(。,' ')“/>输出串联的使用新行字符(它具有10或十六进制A的代码)将当前节点(即与模板匹配)的steing值。可以使用*字符引用*通过其代码输出任何字符 - 在形成'xxx;'(这是十进制)或'&#xabcd;'(这是十六进制)。 – 2011-05-28 13:59:19
“所有的指南都太模糊,无法帮助我解决这个问题或太深”你可能已经错过了W3C或谷歌或搜索SO。 – 2011-05-27 19:27:37