XSLT 和带有副本的基本 URI - 为什么 uri 从 XML 文件更改为 XSLT 文件?
XSLT and base URIs with copy-of - Why does the uri change from the XML-file to the XSLT-file?
给定以下样式表
<?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>
动机: 在 "real world stylesheet" 中,我使用模板来包含其他 XML 来源。它们在源 XML 本身中指定(href 属性中的相对路径)。
<xsl:template match="include" mode="includes">
<xsl:copy-of select="document(@href, .)/*"/>
</xsl:template>
来自Spec:
The base URI of a node is copied, except in the case of an element node having an xml:base attribute
我的问题:
首先,我想知道如何从 XML 文件而不是 XSLT 文件中 preserve/set/copy 基本 URI。
其次,我不明白and/or的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>
至于理解
<xsl:variable name="doc">
<xsl:copy-of select="." />
</xsl:variable>
请参阅 https://www.w3.org/TR/xslt-30/#temporary-trees 其中说:
The construct:
<xsl:variable name="tree"><a/></xsl:variable>
can be regarded as a shorthand for:
<xsl:variable name="tree" as="document-node()"><xsl:document validation="preserve"><a/></xsl:document></xsl:variable>
然后解释 "The base URI of the document node is taken from the base URI of the variable binding element in the stylesheet."。所以这就解释了为什么在这种情况下基本 URI 是样式表 URI。如果你想改变它,你可以根据需要在 xsl:variable
绑定元素上使用 xml:base
。
我目前不确定 <xsl:copy-of select="document(@href, .)/*"/>
与您在问题中首先描述的问题有什么关系,您必须详细说明 where/how 在这种情况下您遇到的基本 URI 问题。
我一直不确定如何解释 "why?" 问题。一种解释是"where in the spec does it say this should happen?"另一种解释是"why did the authors of the spec decide to make it behave this way?"
Martin Honnen 已将您指向规范中规定使用 xsl:variable 创建为临时树的文档的基本 URI 的部分。至于为什么这样设计:好吧,历史上准确的答案需要大量的档案搜索,即使那样也很困难,因为答案通常很简单,没有人提出任何替代方案。 XSLT 1.0 说每个节点都有一个基本 URI,但据我所知,它没有说明构造节点的基本 URI 应该是什么;这是在 XSLT 2.0 中添加的。我不认为使用 xsl:variable 构造的文档节点的基本 URI 真的可以是样式表基本 URI 以外的任何东西(此时没有其他真正可用的),但是 5.7.1 中的规则(构造复杂内容)规则 10 "When copying an element or processing instruction node, its base URI property is changed to be the same as that of its new parent, unless it has an xml:base attribute (see [XML Base]) that overrides this." 当然可以有不同的写法,我认为很可能对这个选择进行了辩论,但我现在不记得争论的具体内容。坦率地说,这有点学术性,因为最终结果树最有可能的形式是序列化 XML 或 DOM,并且无论如何都不会保留节点的基本 URI。
给定以下样式表
<?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>
动机: 在 "real world stylesheet" 中,我使用模板来包含其他 XML 来源。它们在源 XML 本身中指定(href 属性中的相对路径)。
<xsl:template match="include" mode="includes">
<xsl:copy-of select="document(@href, .)/*"/>
</xsl:template>
来自Spec:
The base URI of a node is copied, except in the case of an element node having an xml:base attribute
我的问题:
首先,我想知道如何从 XML 文件而不是 XSLT 文件中 preserve/set/copy 基本 URI。
其次,我不明白and/or的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>
至于理解
<xsl:variable name="doc">
<xsl:copy-of select="." />
</xsl:variable>
请参阅 https://www.w3.org/TR/xslt-30/#temporary-trees 其中说:
The construct:
<xsl:variable name="tree"><a/></xsl:variable>
can be regarded as a shorthand for:
<xsl:variable name="tree" as="document-node()"><xsl:document validation="preserve"><a/></xsl:document></xsl:variable>
然后解释 "The base URI of the document node is taken from the base URI of the variable binding element in the stylesheet."。所以这就解释了为什么在这种情况下基本 URI 是样式表 URI。如果你想改变它,你可以根据需要在 xsl:variable
绑定元素上使用 xml:base
。
我目前不确定 <xsl:copy-of select="document(@href, .)/*"/>
与您在问题中首先描述的问题有什么关系,您必须详细说明 where/how 在这种情况下您遇到的基本 URI 问题。
我一直不确定如何解释 "why?" 问题。一种解释是"where in the spec does it say this should happen?"另一种解释是"why did the authors of the spec decide to make it behave this way?"
Martin Honnen 已将您指向规范中规定使用 xsl:variable 创建为临时树的文档的基本 URI 的部分。至于为什么这样设计:好吧,历史上准确的答案需要大量的档案搜索,即使那样也很困难,因为答案通常很简单,没有人提出任何替代方案。 XSLT 1.0 说每个节点都有一个基本 URI,但据我所知,它没有说明构造节点的基本 URI 应该是什么;这是在 XSLT 2.0 中添加的。我不认为使用 xsl:variable 构造的文档节点的基本 URI 真的可以是样式表基本 URI 以外的任何东西(此时没有其他真正可用的),但是 5.7.1 中的规则(构造复杂内容)规则 10 "When copying an element or processing instruction node, its base URI property is changed to be the same as that of its new parent, unless it has an xml:base attribute (see [XML Base]) that overrides this." 当然可以有不同的写法,我认为很可能对这个选择进行了辩论,但我现在不记得争论的具体内容。坦率地说,这有点学术性,因为最终结果树最有可能的形式是序列化 XML 或 DOM,并且无论如何都不会保留节点的基本 URI。