如何使用Nokogiri在XSL中定位名称空间XML属性



假设我有一个部分看起来像这样的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>

相关内容

  • 没有找到相关文章

最新更新