Subject: Re: [xsl] preserving the base URI origin of content inlined from files From: "G. Ken Holman g.ken.holman@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Wed, 31 May 2023 18:37:41 -0000 |
Hi everyone,
I was writing a stylesheet that analyzed other stylesheets (<https://github.com/dita-ot/dita-ot/issues/4207>https://github.com/dita-ot/dita-ot/issues/4207). I wanted to inline sub-stylesheets referenced by <xsl:include> and <xsl:import>, but I also wanted to determine the origin of any element (top-level or inlined) using base-uri().
When the sub-stylesheets are retrieved and inlined via document(), its base URI property is not preserved. In
<https://www.w3.org/TR/xslt-30/#constructing-complex-content>https://www.w3.org/TR/xslt-30/#constructing-complex-content
it says the following:
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. If the copied element has an xml:base attribute, its base URI is the value of that attribute, resolved (if it is relative) against the base URI of the new parent node.
(Thanks to Martin for pointing me to this statement!)
To inline the content and remember its origin, we can define an xml:base attribute for the inlined root element as follows:
<!-- mode="inline":
inline imported/included stylesheets -->
<xsl:mode name="inline" on-no-match="shallow-copy"/>
<xsl:template match="(xsl:import|xsl:include)[@href]" mode="inline">
<xsl:variable name="target-uri" as="xs:anyURI" select="resolve-uri(@href, base-uri(.))"/>
<xsl:variable name="doc" as="document-node()?" select="$target-uri[doc-available(.)] ! document(.)"/>
<xsl:for-each select="$doc/node()">
<xsl:choose>
<xsl:when test=". instance of element()">
<xsl:copy select=".">
<xsl:attribute name="xml:base" select="base-uri($doc)"/> <!-- explicitly copy xml:base of root element -->
<xsl:apply-templates select="@*|node()" mode="#current"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="#current"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
I wanted to preserve any comment/PI nodes outside the root element of the inlined document, and I couldn't think of a more elegant way of doing that than the code above.
I hope this helps someone who needs to do something similar!
----- Chris Papademetrious
Tech Writer, Implementation Group
(610) 628-9718 home office
(570) 460-6078 cell
<http://www.mulberrytech.com/xsl/xsl-list>XSL-List info and archive
<http://lists.mulberrytech.com/unsub/xsl-list/96802>EasyUnsubscribe (<>by email)
-- Contact info, blog, articles, etc. http://www.CraneSoftwrights.com/s/ | Check our site for free XML, XSLT, XSL-FO and UBL developer resources | Streaming hands-on XSLT/XPath 2 training class @US$125 (5 hours free) | Essays (UBL, XML, etc.) http://www.linkedin.com/today/author/gkholman |
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] preserving the base URI origi, Chris Papademetrious | Thread | |
Re: [xsl] [XSL 3.0] Function that c, Piez, Wendell A. (Fe | Date | Re: [xsl] [XSL 3.0] Function that c, Dimitre Novatchev dn |
Month |