我知道xsl:attribute-set
的存在是为了允许一组XML属性在一个名称下分组,然后可以在以后轻松地将其应用于几个类似的元素。
我知道名称空间不是属性,不能使用它来设置。
然而在Saxon9.8EE中,我注意到这是有效的,我想知道这是否可以使用:
<xsl:attribute-set name="swbml.ir" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:attribute name="version">4-2</xsl:attribute>
<xsl:attribute name="xsi:schemaLocation">http://www.fpml.org/2005/FpML-4-2 /path/to/swbml-ird-main-4-2.xsd</xsl:attribute>
</xsl:attribute-set>
通过将xsi名称空间添加到xsl:attribute-set
本身,它将此名称空间应用于使用swbml.ir
属性集的任何元素。
(当然必须因为其中一个属性位于xsi名称空间中)
所以这个:
<SWBML xmlns="http://www.fpml.org/2005/FpML-4-2" xsl:use-attribute-sets="swbml.ir">
结果:
<SWBML xmlns="http://www.fpml.org/2005/FpML-4-2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="4-2"
xsi:schemaLocation="http://www.fpml.org/2005/FpML-4-2 /path/to/swbml-ird-main-4-2.xsd">
这正是我想要的。但感觉我可能正在扩展属性集的预期用例?
具体来说,如果我尝试更进一步并像这样添加xmlns="http://www.fpml.org/2005/FpML-4-2"
:
<xsl:attribute-set name="swbml.ir" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.fpml.org/2005/FpML-4-2">
默认的xmlns不适用于<SWBML>
- 这是我所期望的。
所以 - 规则是属性集将添加任何命名空间,以便限定集合包含的任何属性,但是不会添加任何其他命名空间?或者我误入了未定义的领域?
答案 0 :(得分:2)
您的理解基本上是正确的,因为如果存在绑定到命名空间的内容,并且您将其包含在输出中,那么命名空间将随之而来。但是,您碰巧在属性集上声明了它并不重要。它可以在样式表的其他位置声明,例如在xsl:stylesheet元素上,在范围内并在属性集中引用。
根据您提出的示例,您可以将xsi
命名空间前缀的声明从xsl:attribute-set
移到xsl:stylesheet
元素之外,它仍会显示在如果属性集应用于元素,则输出:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xsi">
<xsl:output method="xml"/>
<xsl:attribute-set name="swbml.ir">
<xsl:attribute name="version">4-2</xsl:attribute>
<xsl:attribute name="xsi:schemaLocation">http://www.fpml.org/2005/FpML-4-2 /path/to/swbml-ird-main-4-2.xsd</xsl:attribute>
</xsl:attribute-set>
<xsl:template match="/">
<SWBML xmlns="http://www.fpml.org/2005/FpML-4-2" xsl:use-attribute-sets="swbml.ir"/>
</xsl:template>
</xsl:stylesheet>
如果属性集未应用于内容,它将不会出现在输出中:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xsi">
<xsl:output method="xml"/>
<xsl:attribute-set name="swbml.ir">
<xsl:attribute name="version">4-2</xsl:attribute>
<xsl:attribute name="xsi:schemaLocation">http://www.fpml.org/2005/FpML-4-2 /path/to/swbml-ird-main-4-2.xsd</xsl:attribute>
</xsl:attribute-set>
<xsl:template match="/">
<SWBML xmlns="http://www.fpml.org/2005/FpML-4-2" />
</xsl:template>
</xsl:stylesheet>
请注意,我在两个示例中都使用了exclude-result-prefixes
,以确保在未使用时从输出中删除xsi
namepsace。否则,范围内的命名空间可能会出现在输出中,即使它没有应用于任何内容。
答案 1 :(得分:1)
是的,这将有效:正如@MadsHansen指出的那样,当你使用<xsl:attribute name="p:u"/>
时,唯一真正重要的是p
元素上的前缀xsl:attribute
被声明的地方本身,或其祖先之一。如果在xsl:attribute-set
本身的级别上声明它很方便,那就好了,做到这一点。
这里需要注意的是,这并不适用于QName值属性。如果你想做
<xsl:attribute name="xsi:type">xs:date</xsl:attribute>
然后你可以通过让它在xsi
指令的范围内来获得结果文档中声明的前缀xsl:attribute
,但对于xs
前缀,你需要稍微工作一下更难(因为XSLT处理器不知道属性值xs:date是QName)。在这种情况下,您需要明确确保结果树中的某些包含元素声明xs
命名空间。