[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

preserving the base URI origin of content inlined from

Subject: preserving the base URI origin of content inlined from files
From: "Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 31 May 2023 11:44:53 -0000
 preserving the base URI origin of content inlined from
Hi everyone,

I was writing a stylesheet that analyzed other stylesheets
(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

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

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.