我正在使用 SAXON 和 XSL 3.0 转换来生成 RDF 文件作为我的目标输出。根据 W3C RDF 规范,为了正确解析相关 IRI,我需要在文件生成的 标头中指定一个 xml:base
我有以下 example.xml 作为 XSLT 3.0 转换的输入:
<?xml version="1.0" encoding="UTF-8"?>
<Catalog xmlns="http://langdale.com.au/2005/Message#"
xmlns:m="http://iec.ch/TC57/2013/CPSM-ShortCircuit#"
ontologyURI="http://iec.ch/TC57/2013/CIM-schema-cim16"
baseURI="http://iec.ch/TC57/2013/CPSM-ShortCircuit#"
name="ShortCircuit">
<Note>This profile represents the equipment of the power system and their hierarchical relationships.</Note>
<ComplexType name="ACDCTerminal"
baseClass="http://iec.ch/TC57/2013/CIM-schema-cim16#ACDCTerminal"
package="Core"
packageURI="http://iec.ch/TC57/2013/CIM-schema-cim16#Package_Core"
minOccurs="0"
maxOccurs="unbounded">
<Comment>An electrical connection point (AC or DC) to a piece of conducting equipment.</Comment>
<SuperType name="IdentifiedObject"
baseClass="http://iec.ch/TC57/2013/CIM-schema-cim16#IdentifiedObject"/>
</ComplexType>
<ComplexType name="IdentifiedObject"
baseClass="http://iec.ch/TC57/2013/CIM-schema-cim16#IdentifiedObject"
package="Core"
packageURI="http://iec.ch/TC57/2013/CIM-schema-cim16#Package_Core"
minOccurs="0"
maxOccurs="unbounded">
<Comment>This is a root class to provide common identification for all classes needing identification and naming attributes.</Comment>
<Simple dataType="http://www.w3.org/2001/XMLSchema#string"
xstype="string"
name="mRID"
baseProperty="http://iec.ch/TC57/2013/CIM-schema-cim16#IdentifiedObject.mRID"
minOccurs="0"
maxOccurs="1">
<Comment>Master resource identifier issued by a model authority.</Comment>
</Simple>
</ComplexType>
</Catalog>
所应用的 XSLT 3.0 转换如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet exclude-result-prefixes="a" version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cims="http://iec.ch/TC57/1999/rdf-schema-extensions-19990926#"
xmlns:a="http://langdale.com.au/2005/Message#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
<xsl:output xmlns:xalan="http://xml.apache.org/xslt" method="xml" omit-xml-declaration="no" indent="yes" xalan:indent-amount="4" />
<!-- baseURI and ontologyURI parameters passed in. baseURI is for the profile and ontologyURI for the xml:base attribute -->
<xsl:param name="baseURI"/>
<xsl:param name="ontologyURI"/>
<xsl:param name="newline"><xsl:text>
</xsl:text></xsl:param>
<xsl:template match="a:Catalog">
<rdf:RDF xml:base="{$ontologyURI}">
<xsl:variable name="rdf" as="node()*">
<xsl:apply-templates select=".//*"/>
</xsl:variable>
<xsl:perform-sort select="$rdf">
<xsl:sort select="@rdf:about"/>
</xsl:perform-sort>
</rdf:RDF>
</xsl:template>
<!-- NOTE: remaining template definitions not needed for the example have been removed -->
</xsl:stylesheet>
当我指定所示的 xml:base 属性(即
<rdf:RDF xml:base="{$ontologyURI}">
)时,执行过程中会失败。如果我对值进行硬编码,它会成功生成(即硬编码为 <rdf:RDF xml:base="http://iec.ch/TC57/2013/CIM-schema-cim16">
),但我需要能够以编程方式传递不同的基本 URI。
当我保留表达式并删除 xml: 前缀(即
<rdf:RDF base="{$ontologyURI}">
)时,XSLT 将使用 RDF 标头输出,如下所示。但是,根据 W3C RDF 规范,我需要 baseURI 的完全前缀属性 (xml:base) 来解析相对 IRI。
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:cims="http://iec.ch/TC57/1999/rdf-schema-extensions-19990926#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
base="http://iec.ch/TC57/2013/CIM-schema-cim16">
...
...
</rdf:RDF>
样式表中
xml:base
的使用被解释为它出现的元素的基本属性。就像 xml:id
使用它作为文字属性一样,将其语义放置在样式表中的元素上。
您可以通过以下方式避免这种情况:
<rdf:RDF>
<xsl:attribute name="xml:base" select="$ontologyURI"/>
...