假设我有一个部分看起来像这样的XML:
... lorem ipsum dolor sit amet, <ext-link href="http://www.consectetur.org/">consectetur</ext-link> adipiscing elit ...
我可以很容易地在XSD中使用
定位URL<xsl:template match="ext-link">
<a href="{@href}"><xsl:apply-templates/></a>
</xsl:template>
但是当我的XML看起来像这样时,我就不知所措了:
... lorem ipsum dolor sit amet, <ext-link xlink:href="http://www.consectetur.org/">consectetur</ext-link> adipiscing elit ...
这行不通:
<xsl:template match="ext-link">
<a href="{@xlink:href}"><xsl:apply-templates/></a>
</xsl:template>
@xlink
和@href
也没有。我在这里遗漏了哪些重要的XML/XSL知识?
由于我使用Nokogiri进行解析,我可能缺少的是如何告诉它关联名称空间—我不确定在哪里做这件事。输入XML和XSL,像这样
doc = Nokogiri::XML(File.read('/some/xml/path'))
xslt = Nokogiri::XML(File.read('/some/xsl/path'))
result = xslt.transform(doc)
使用这个,所有的{@xlink}
, {@href}
或{@xlink:href}
在我的XML渲染没有任何结果。
如果源文档没有使用名称空间(可能声明以某种方式被删除了),那么您需要选择没有名称空间的属性和"本地"名称xlink:href
。这对于XPath来说有点棘手,因为它会将:
解释为分隔名称空间,但是您可以使用name()
函数这样做:
<xsl:template match="ext-link">
<a href="{@*[name() = 'xlink:href']}"><xsl:apply-templates/></a>
</xsl:template>
源XML文档将在树的更高位置声明名称空间,假设这是标准的XLink机制,将是
xmlns:xlink="http://www.w3.org/1999/xlink"
为了引用具有本地名称href
和名称空间URI http://www.w3.org/1999/xlink
的属性,需要将相同的名称空间URI绑定到样式表中的前缀,然后在XPath表达式中使用该前缀。例如
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="..."
xmlns:xlink="http://www.w3.org/1999/xlink">
<xsl:template match="ext-link">
<a href="{@xlink:href}"><xsl:apply-templates/></a>
</xsl:template>
</xsl:stylesheet>
在本例中,xlink
是该URI的常规前缀,但通常该前缀不必与使用的源文档相同,重要的是它映射到正确的URI。这样也可以:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="..."
xmlns:xl="http://www.w3.org/1999/xlink">
<xsl:template match="ext-link">
<a href="{@xl:href}"><xsl:apply-templates/></a>
</xsl:template>
</xsl:stylesheet>