使用XSL文件将XML转换为HTML时,我试图访问XML文件的!ENTITY
声明中的!DOCTYPE
元素。在XML中,我有一个widget
元素,它具有一个与!ENTITY
名称相对应的属性,并且我希望XSLT将其转换为!ENTITY
的值。
XML文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root[
<!ENTITY Widget_Manual "Widget_Manual_File_Name.pdf" >
]>
<root>
<!-- I want to convert this to "Widget_Manual_File_Name.pdf" in the transform -->
<widget entityIdent="Widget_Manual" />
</root>
XSLT文件
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head />
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="widget">
<!-- Embed PDF -->
<object width="800" height="600" type="application/pdf">
<xsl:attribute name="data">
<!-- How do I access the !ENTITY's value using the @entityIdent attribute? -->
<xsl:value-of select="@entityIdent" />
</xsl:attribute>
</object>
</xsl:template>
</xsl:stylesheet>
实际输出
<object width="800" height="600" type="application/pdf" data="Widget_Manual"></object>
所需的输出
<object width="800" height="600" type="application/pdf" data="Widget_Manual_File_Name.pdf"></object>
答案 0 :(得分:1)
最好只在XML中使用一个实体,以便XML解析器在解析文档时会为您扩展该实体。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root[
<!ENTITY Widget_Manual "Widget_Manual_File_Name.pdf" >
]>
<root>
<!-- I want to convert this to "Widget_Manual_File_Name.pdf" in the transform -->
<widget entityIdent="&Widget_Manual;" />
</root>
如果您没有XML的控制权,但想在XSLT中执行查找/替换,那么您将不得不跳过一些麻烦。 XSLT对已经解析的XML进行操作,并且DTD内容不能在XML信息集中直接寻址。
但是,您可以获得base-uri()
,然后使用unparsed-text()
来读取XML作为字符串,然后将replace()
与具有捕获组(或子字符串函数)的正则表达式一起使用)以获取ENTITY的值。
可以使用以下XSLT 2.0样式表:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@entityIdent">
<xsl:attribute name="{name()}">
<xsl:value-of select="replace(
unparsed-text(base-uri()),
concat('.*!ENTITY ', ., ' "(.+?)".*'),
'$1',
's')"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>