2012-07-25 150 views
-1

肯定我将永远找不到成功的思维在XSLT ...XSLT转换XML到XHTML

以下是我有:

<par font="Arial" size="24">text 24</par> 
    <par font="Arial" size="12">text 12</par> 
    <par font="Times New Roman" size="12">text times 12</par> 

这里是我想要的东西:

<font style="font-family:Arial"><font style="font-size:24">text 24</font></font> 
    <font style="font-family:Arial"><font style="font-size:12">text 12</font></font> 
    <font style="font-family:Times New Roman"><font style="font-size:12">text times 12</font></font> 

当然,这样的事情也不错,但对我来说这个解决方案似乎更复杂:

<font style="font-family:Arial;font-size:24">text 24</font> 
<font style="font-family:Arial;font-size:12">text 12</font> 
<font style="font-family:Times New Roman;font-size:12">text times 12</font> 

我认为(但我可能是错的)我将不得不为每个大小和每种字体指定一些代码。这不是问题,因为我的xml中只有很少的大小和字体可用。您的帮助

很多很多的感谢,我开始失去我的头发试图通过自己做...

+0

你真的想要哪个输出?多个''(您的第一个输出示例)或单个''(您的第二个输出示例)? – 2012-07-25 15:13:53

+0

此外,** par **元素是否总是具有** font **属性和** size **属性,或者它有可能缺少其中一个属性(例如仅与字体,但不是大小)? – 2012-07-25 15:16:23

+0

@DevNull:2nd比较好。 – Sebange 2012-07-25 15:19:02

回答

3

你可以做这样的事情:

XML输入(修改为良好形成)

<doc> 
    <par font="Arial" size="24">text 24</par> 
    <par font="Arial" size="12">text 12</par> 
    <par font="Times New Roman" size="12">text times 12</par> 
</doc> 

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="doc"> 
     <html> 
      <xsl:apply-templates/> 
     </html> 
    </xsl:template> 

    <xsl:template match="par"> 
     <font> 
      <xsl:attribute name="style"> 
       <xsl:apply-templates select="@*"/> 
      </xsl:attribute> 
      <xsl:apply-templates select="node()"/> 
     </font> 
    </xsl:template> 

    <xsl:template match="par/@size"> 
     <xsl:value-of select="concat('font-size: ',.,';')"/> 
    </xsl:template> 
    <xsl:template match="par/@font"> 
     <xsl:value-of select="concat('font-family: ',.,';')"/> 
    </xsl:template> 

</xsl:stylesheet> 

输出

<html> 
    <font style="font-family: Arial;font-size: 24;">text 24</font> 
    <font style="font-family: Arial;font-size: 12;">text 12</font> 
    <font style="font-family: Times New Roman;font-size: 12;">text times 12</font> 
</html> 

此外,您还可以将match="par"更改为match="par[@font or @size]",如果你只想输出<font>如果它有一个fontsize属性。

+0

完美的作品! – Sebange 2012-07-25 15:35:00

+0

@DevNull这是一个很好的答案,但它并不完美。您的样式属性值中包含多余的分号。 – 2012-07-25 15:55:06

+0

@ SeanB.Durkin - 尾随分号不是必需的,但它也不会伤害任何东西。 – 2012-07-25 17:25:00

0

对DevNull的调整。他是第一个正确答案。詹姆斯的答案是错的。

我只是是非常迂腐这里,但实际最简单的解决方案严密....是<击鼓声/> ....

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 

<xsl:template match="/"> 
<xsl:for-each select="*/par"> 
    <font style="{ string-join(
    for $a in (@size|@font) return 
    concat('font-', if ($a except @font) then 'size' else 'family', ':', $a), 
    ';')}"> 
    <xsl:copy-of select="node()"/> 
    </font> 
</xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

上述XSLT 2.0样式表将改变此输入。 ..

<doc> 
    <par font="Arial" size="24">text 24</par> 
    <par font="Arial" size="12">text 12</par> 
    <par font="Times New Roman" size="12">text times 12</par> 
    <par font="Courier">No size specified!</par> 
    <par size="16">No font specified!</par> 
</doc> 

...这个...输出

<font style="font-family:Arial;font-size:24">text 24</font> 
<font style="font-family:Arial;font-size:12">text 12</font> 
<font style="font-family:Times New Roman;font-size:12">text times 12</font> 
<font style="font-family:Courier">No size specified!</font> 
<font style="font-size:16">No font specified!</font> 

一个小模板,style属性值中没有多余的分号!

没有提及需要什么XSLT版本。所以如果OP在XSLT 1.0上,那么这个解决方案可能对OP没有用。

+0

B转换是由IE完成的我只是做了一些搜索,它似乎只接受XSLT-1.0。我添加标签。 – Sebange 2012-07-27 08:55:47