Edit online

How to Use XPath Expressions in CSS

How to Write XPath Expressions

To use XPath expressions in CSS, you need to use the oxy_xpath() function. These XPath expressions are used to extract the content from the HTML merged DITA map document.

The following example shows how to display the product name meta-information before the front page title:
*[class~="front-page/front-page-title"]:before {
    text-align: left;
    content: oxy_xpath("(//*[contains(@class, 'topic/prodname')]/text())[1]");
    display:block;
}
Important: Do not use the DITA element names directly. You must use the DITA @class attribute instead, as these attributes are propagated to the HTML elements while the element names can be lost. By using the class selectors, you also cover DITA specializations.
Tip: Use the "[1]" XPath predicate to select the first value from the document. Do not forget the parenthesis between the node to be selected.

For example: oxy_xpath("(//*[contains(@class, 'topic/prodname')]/text())[1]").

Note that the meta-information might be copied multiple times in the output, inherited by the <topicref> elements, so you might get more values than expected.

Other Notes:
  • You can call the oxy_xpath() function in string-set property.
  • You can use content extracted using the oxy_xpath() function in both pseudo-elements and @page at-rules.
  • Do not use strings as values for pseudo-elements content because they are not supported in them.

How to Debug XPath Expressions

Suppose that you need to display the publication author in the bottom-left part of the cover page.

The ditamap content is the following:
<map>
  <title>The Art of Bike Repair</title>
  <topicmeta>
    <author>John Doe</author>
  </topicmeta>
  ...
</map>
To debug an XPath expression:
  1. Read the XPath Expressions Guidelines.
  2. Launch the transformation of the DITA map using your customization CSS.
  3. Open the [MAP_NAME].merged.html file (from the output folder) in Oxygen XML Editor/Author. You will find this inside the HTML:
    <div class="- front-page/front-page front-page">
      <div class="- map/topicmeta topicmeta">
        <div class="- topic/author author">John Doe</div>
      </div>
      <div class="- front-page/front-page-title front-page-title">
        <div class="- topic/title title">The Art of Bike Repair</div>
      </div>
    </div>
  4. Activate the XPath Builder view (Window > Show View > XPath/XQuery Builder).
  5. Paste your XPath expression (for example: //*[contains(@class, "front-page/front-page")]/*[contains(@class, "map/topicmeta")]/*[contains(@class, "topic/author")]/text()) and click the Execute XPath button. Check if it returns the expected results.
  6. Copy the expression in your customization CSS and define the rules that will use it. For example:
    :root {
      string-set: author oxy_xpath('//*[contains(@class, "front-page/front-page")]\
      /*[contains(@class, "map/topicmeta")]/*[contains(@class, "topic/author")]/text()');
    }
    
    @page front-page {
      @bottom-left {
        content: "Created by " string(author);
      }
    }
    Note: The "\" character used in the expression allows the multi-line display without breaking the query.
  7. Run the transformation again to obtain the desired output.
Note: The XPath builder has a function that allows it to display the document path of the current element from the editor (Settings drop-down menu > Update on cursor move). Alternatively, you can right-click the element in the merged document and select the Copy XPath action, then paste it in the XPath builder.