给出以下样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template name="start">
<base-uris>
<node-base-uri>
<xsl:value-of select="base-uri(.)" />
</node-base-uri>
<node-base-uri-from-copy>
<xsl:variable name="doc">
<xsl:copy-of select="." />
</xsl:variable>
<xsl:value-of select="base-uri($doc)" />
</node-base-uri-from-copy>
</base-uris>
</xsl:template>
</xsl:stylesheet>
使用以下命令从命令行使用Saxon转换任意XML文件后:
java net.sf.saxon.Transform -s:xml/index.xml -xsl:xsl/base-uri.xsl -it:start
我期望指向XML源文件的基URI的值相同。但第二种情况下的基URI(带有副本)指向XSLT文件。
<base-uris>
<node-base-uri>file:/xml/index.xml</node-base-uri>
<node-base-uri-from-copy>file:/xsl/base-uri.xsl</node-base-uri-from-copy>
</base-uris>
动机:在“真实世界样式表”中,我使用模板来包含其他XML源。它们在源XML本身中指定(href属性中的相对路径)。
<xsl:template match="include" mode="includes">
<xsl:copy-of select="document(@href, .)/*"/>
</xsl:template>
来自Spec:
复制节点的基URI,除非元素节点具有xml:base属性
我的问题:
首先,我想知道,如何从XML文件而不是XSLT文件中保留/设置/复制基URI。
其次,我不了解Spec和/或不了解xml:base属性的事情。我只是想:我的代码中没有看到任何xml:base属性,因此应该复制节点的基URI。
最后评论:
到处玩,我想出了类似这样的东西,感觉很笨拙或只是错误的方式:
<node-base-uri-work-around>
<xsl:variable name="doc">
<wrapper>
<xsl:attribute name="xml:base" select="base-uri(.)" />
<xsl:copy-of select="." />
</wrapper>
</xsl:variable>
<xsl:value-of select="base-uri($doc/wrapper)" />
</node-base-uri-work-around>
答案 0 :(得分:2)
至于理解
<xsl:variable name="doc">
<xsl:copy-of select="." />
</xsl:variable>
请参阅https://www.w3.org/TR/xslt-30/#temporary-trees,其中说:
构造:
<xsl:variable name="tree"><a/></xsl:variable>
可以视为:
的简写
<xsl:variable name="tree" as="document-node()"><xsl:document validation="preserve"><a/></xsl:document></xsl:variable>
然后解释说“文档节点的基URI来自样式表中变量绑定元素的基URI。”这就解释了为什么在这种情况下基URI是样式表URI。如果您想要更改它,可以根据需要在xml:base
绑定元素上使用xsl:variable
。
我目前不确定<xsl:copy-of select="document(@href, .)/*"/>
如何与您在问题中首次描述的问题相关,您必须详细说明在这种情况下您遇到基本URI问题的位置/方式。
答案 1 :(得分:2)
我不知道如何解释“为什么?”的问题。一种解释是“规范中的哪个位置会说这应该发生?”另一种解释是“为什么规范的作者决定让它以这种方式运行?”
Martin Honnen向您指出了规范部分,该部分规定了使用xsl:variable创建为临时树的文档的基URI。至于为什么它的设计是这样的:嗯,历史上准确的答案需要在档案中进行大量的拖网,即使这样也很难,因为答案很简单,没有人提出任何替代方案。 XSLT 1.0说每个节点都有一个基URI,但据我所知,它没有说明构造节点的基URI应该是什么;这是在XSLT 2.0中添加的。我不认为使用xsl:variable构造的文档节点的基本URI可能实际上不是样式表基本URI(此时没有其他任何内容可用),而是5.7.1中的规则(构造复杂内容) )规则10“复制元素或处理指令节点时,其基本URI属性被更改为与其新父节点相同,除非它具有覆盖此属性的xml:base属性(请参阅[XML Base])。”当然可以用不同的方式写出来,我认为这个选择很可能是有争议的,但我现在还记不起这些论点。坦率地说,它有点学术性,因为最终结果树最可能的形式是序列化XML或DOM,并且无论如何都不会保留节点的基本URI。