XSLT to rename link targets in result-document() - xslt

When splitting a deeply nested XML document into multiple output files using result-document(), is there a method to rewrite the #href values to point to ids inside the new documents? For example, splitting a book into multiple documents based on each becoming a new file, named with book-part/#id. In output file for chapter 1 there may be a link to a target in output file for chapter 2, which link value used to be relative within the single file. Now this link pointing to a different file should have the file name of chapter 2 followed by # and the original target value. There are changes to make the proper linking element (related-object), too, but it is the target value that I'm trying to generate specifically.
i.e link target pattern: [outputfilename.xml]#[original-filetarget-id]
It seems that I need to gather the values of each #rid in the original file and check before I insert the filename if the target will be in a different file and write the output #document-id according to the file in which it will be output. But I'm having trouble understanding how I would know the output file name and where in the XSLT to rewrite the target.
source xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//NLM//DTD Book DTD v2.1 20050630//EN" "book.dtd">
<book dtd-version="3.0">
<book-meta>
<book-id>123.4567890</book-id>
</book-meta>
<body>
<book-part book-part-type="chapter" id="book.123.4567890.ch01">
<book-part-meta>
<title-group>
<title>Chapter 1</title>
</title-group>
</book-part-meta>
<body>
<p> some text with a <xref rid="a">link to chapter 1</xref></p>
<p> some text with a <xref rid="b">link to chapter 2</xref></p>
<p id="a">a target id in chapter 1</p>
</body>
</book-part>
<book-part book-part-type="chapter" id="book.123.4567890.ch02">
<book-part-meta>
<title-group>
<title>Chapter 2</title>
</title-group>
</book-part-meta>
<body>
<p> some text with a <xref rid="a">link to chapter 1</xref></p>
<p> some text with a <xref rid="b">link to chapter 2</xref></p>
<p id="b">a target id in chapter 1</p>
</body>
</book-part>
</body>
</book>
output book.123.4567890.ch01.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//NLM//DTD Book DTD v2.1 20050630//EN" "book.dtd">
<book dtd-version="3.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oasis="http://docs.oasis-open.org/ns/oasis-exchange/table">
<book-meta>
<book-id>123.4567890</book-id>
</book-meta>
<body>
<book-part book-part-type="chapter" id="book.123.4567890.ch01">
<book-part-meta>
<title-group>
<title>Chapter 1</title>
</title-group>
</book-part-meta>
<body>
<p> some text with a <xref rid="a">link to chapter 1</xref></p>
<p> some text with a <related-object document-type="chapter" object-id="book.123.4567890.ch02.xml#b">link to chapter 2</related-object></p>
<p id="a">a target id in chapter 1</p>
</body>
</book-part>
</body>
</book>
output book.123.4567890.ch02.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//NLM//DTD Book DTD v2.1 20050630//EN" "book.dtd">
<book dtd-version="3.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oasis="http://docs.oasis-open.org/ns/oasis-exchange/table">
<book-meta>
<book-id>123.4567890</book-id>
</book-meta>
<body>
<book-part book-part-type="chapter" id="book.123.4567890.ch02">
<book-part-meta>
<title-group>
<title>Chapter 2</title>
</title-group>
</book-part-meta>
<body>
<p> some text with a <related-object document-type="chapter" object-id="book.123.4567890.ch01.xml#a">link to chapter 1</related-object></p>
<p> some text with a <xref rid="b" >link to chapter 2</xref></p>
<p id="b">a target id in chapter 1</p>
</body>
</book-part>
</body>
</book>

The short answer is: yes, you have understood correctly what you need to do.
You need to figure out, for each hyperlink, whether its target will be in the same output file as the source of the link, or a different one. And you have correctly identified the challenge here: knowing what the new file name will be. It's not really as difficult as it may look at first; just take a deep breath and work it out.
You are at an xref element; it has an rid attribute. You want to know: will the xref and the target be in the same output file or different ones? To decide this, you must
Ascend from the xref element to the containing book-part, and figure out what its filename will be. Put this value in a variable (fn-xref).
Go to the target element (id(#rid)) and then ascend from that element to the containing book-part, and figure out what its filename will be. Put this value in a variable (fn-rid).
Compare the values of $fn-xref and $fn-rid. If they are equal, do the right thing. If they differ, do the other right thing.
I'm guessing you don't need help turning this prose description into XSLT, but speak up if you do.

Related

How do I write an XSLT script to import data from a spreadsheet into an HTML file?

I need to create an XSLT script to import content from a spreadsheet into an HTML file.
My spreadsheet has 3 columns I need to import.
I'll have the spreadsheet data exported to HTML in this format:
<table class="tableizer-table">
<thead>
<tr class="tableizer-firstrow">
<th>CARD ID</th>
<th>PROMPT</th>
<th>RESPONSE</th>
</tr>
</thead>
<tbody>
<tr>
<td>3</td>
<td>Acquisition</td>
<td>In classical conditioning, the process of taking advantage of reflexive
responses to turn a neutral stimulus into a conditioned stimulus.</td>
</tr>
</tbody>
</table>
That data needs to be added to this HTML page:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" designation="" enumeration="" data-uuid="61dac34c7de54289a58698d5bfc8e776">
<head>
<meta charset="utf-8"/>
<link type="text/css" rel="stylesheet" title="default" href="../../assets/css/main.css"/>
<title>usurpmcatfc0001</title>
</head>
<body>
<section property="ktp:document" typeof="ktp:Document" class="ktp-document">
<section class="ktp-document-meta">
<section property="ktp:metadata" class="ktp-meta"><span property="atom:content-item-name" class="ktp-meta" data-value="usurpmcatfc0001"></span></section>
<section property="ktp:tags" class="ktp-meta"><span property="ktp:topic" class="ktp-meta">MCAT</span><span property="ktp:topic" class="ktp-meta">Behavioral Sciences</span><span property="ktp:subsubtopic" class="ktp-meta">Sensation and Perception</span></section>
</section>
<section property="ktp:document-section" typeof="ktp:flashcards" class="ktp-document-section" data-title="Absolute Threshold">
<p>The minimum of stimulus energy needed to activate a sensory system.</p>
</section>
</section>
</body>
</html>
The data from column 1 needs to feed into the data-value of this section:
<section property="ktp:metadata" class="ktp-meta"><span property="atom:content-item-name" class="ktp-meta" data-value="[COLUMN 1 DATA]"></span></section>
The data from column 2 needs to feed into the data-title and the data from column 3 needs to feed in between the <p></p> tags of this section:
<section property="ktp:document-section" typeof="ktp:flashcards" class="ktp-document-section" data-title="Absolute Threshold">
<p>The minimum of stimulus energy needed to activate a sensory system.</p>
</section>
Any help generating this script would be most appreciated.
Thanks!
If the exported HTML is parseable as XML you can read it simply with the doc function e.g. <xsl:variable name="excel-table" select="doc('exported-table.xml')//table[#class = 'tableizer-table']"/> and of course reading in a column is as easy as e.g. $excel-table/tbody/tr/td[1].
So set up templates for the nodes you want to manipulate e.g.
<xsl:template match="section[#property = 'ktp:metadata']/span/data-value">
<xsl:attribute name="{name()}" select="$excel-table/tbody/tr/td[1]"/>
</xsl:template>
Of course the base processing will be done by the identity transformation e.g. <xsl:mode on-no-match="shallow-copy"/> in XSLT 3.
The only complication seems to be that the main document is XHTML in the namespace xmlns="http://www.w3.org/1999/xhtml" so you need to set up xpath-default-namespace="http://www.w3.org/1999/xhtml" but if the table export is in no namespace the variable needs to use <xsl:variable name="excel-table" xpath-default-namespace="" select="doc('exported-table.xml')//table[#class = 'tableizer-table']"/> and any selection inside the document needs to do the same e.g. the <xsl:attribute name="{name()}" xpath-default-namespace="" select="$excel-table/tbody/tr/td[1]"/>.

xsl how to direct the html content to xml content through clicking on the html uri link

I have a xml structure like below:
<PAGES>
<PAGE>
<PAGENUMBER>1</PAGENUMBER>
<SECTION>
<SECTIONITEM>
<ITEMNUMBER>1</ITEMNUMBER>
<TITLE>Interactive Forms</TITLE>
<TOPIC>
<SUBTITLE>Intro to Forms & Attributes </SUBTITLE>
<ITEM>1</ITEM>
<PARA>This is the explanation for Topic ITEM 1</PARA>
<GRAPH>This the the link to the GRAPHIC</GRAPH>
</TOPIC>
</SECTIONITEM>
</SECTION>
</PAGE>
....<!-- lots of page blocks-->
</PAGES>
Now I have to generate a html summary that will list the PAGENUMBERs when certain conditions are satisfied and generate an <a href> link for the PAGENUMBER in the html. The request is that when user clicks on the page number link on the html, xml file will be popped up and directed to the related xml content.
Is this possible to link PAGENUMBER to the related xml content using xsl? I don't have enough experience to do this now.
Could anybody give me some suggestion or this could be done using other language like java or javascript?
Many thanks in advance!

Can I have different sections with same place holder in Sitecore

Below is my sublayout called SectionWrapper
<section>
<sc:Placeholder ID="phSectionWrapper" runat="server" Key="phSectionWrapper" />
check this
</section>
I want to achieve is multiple "sections" with different placeholders like
<section>
<caraousal 1 />
check this
</section>
<section>
<caraousal 2 />
check this
</section>
But it's now rendering as
<section>
<caraousal 1 />
check this
<caraousal 2 />
</section>
<section>
check this
</section>
My presentation details are configured on item as below:
SectionWrapper (with some placeholder)
caraousal1 (with placeholder as phSectionWrapper)
SectionWrapper (with some placeholder)
caraousal2 (with placeholder as phSectionWrapper)
Placeholder keys must be unique on the page. You cannot have 2 placeholders on the same page with the same key - Sitecore will not know in which of them should put the components.
Check Sitecore Dynamic Placeholders - from what I remember there are multiple implementations ready to use, e.g.:
https://marketplace.sitecore.net/en/Modules/I/Integrated_Dynamic_Placeholders.aspx
http://johnnewcombeuk.blogspot.com/2012/06/sitecore-part-3-dynamic-placeholders.html

XSLT: Getting XML namespace as an attribute

I have the following xml:
<article article-type="research-article">
<body>
<graphic xlink:href="zee9991370930006.g.eps"/>
<self-uri xlink:title="pdf" xlink:href="zee00813002857.pdf" />
</body>
</article>
I need to convert this to:
<article article-type="research-article" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML">
<body>
<graphic xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="zee9991370930006.g.eps"/>
<self-uri xlink:title="pdf" xlink:href="zee00813002857.pdf" xmlns:xlink="http://www.w3.org/1999/xlink"/>
</body>
</article>
I used the following command in XSLT 2.0 for each of the elements for which namespace attribute is required:
<xsl:namespace name="xlink" select="'http://www.w3.org/1999/xlink'"/>
<xsl:namespace name="mml" select="'http://www.w3.org/1998/Math/MathML'"/>
But the issue is I am getting the namespace attribute only for one element i.e. article. I have declared the namespaces at the beginning of my xslt as well. Can't figure out what is the exact issue. Help of any kind would be truly appreciated. Thanks.
XML generators are not supposed to do what you want. They will produce your XML according to the specs. It is not recommended that you define the same namespaces in all elements that are using them! this makes it verbose, ugly and weird way of doing tings.
What is the problem if the namespace is defined only at the top (root element)? You can use it only in the elements that require it. simple.
(OP's comment: I need it at the root and I have declared it. But it is not available for the nodes under it i.e graphic and self-uri in my case).
Have you checked if you xml is well-formed? If what you post here is the complete xml, then graphic and self-uri should always have the namespace available. You should aim for the following output for the reasons told above.
<article article-type="research-article" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML">
<body>
<graphic xlink:href="zee9991370930006.g.eps"/>
<self-uri xlink:title="pdf" xlink:href="zee00813002857.pdf"/>
</body>
</article>

How can I preserve HTML entities with Diazo?

I have the following simple Diazo rules file:
<rules
xmlns="http://namespaces.plone.org/diazo"
xmlns:css="http://namespaces.plone.org/diazo/css"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<theme href="theme/theme.html" />
<replace css:theme-children="#content" css:content-children=".content" />
</rules>
and theme:
<html>
<body>
<div id="content">
Lorem ipsum ...
</div>
</body>
</html>
The source I want to transform is:
<html>
<body>
<div class="content">
info
</div>
</body>
</html>
What I get is
... info ...
but I want to keep the HTML entities of the href attribute intact. How can I do this with Diazo?
Note numeric character references are not entity references so your title is a bit misleading (the answer for preserving or not entity references such as "& n b s p ; " is very different)
I don't know Diazo but in XSLT if you add
<xsl:output encoding="US-ASCII"/>
to your document then any non ascii characters will be output using numeric references.
However in your example they are in fact ascii characters that are quoted such as "." as "." There isn't any standard way in xslt 1 to do that (and there should never be any reason to do that if the document is going to be processed by a conforming html or xml system). Any such system will expand those references to their characters before processing starts. (Which is why XSLT can not preserve them: they have been removed by the xml parser before XSLT sees the input data.)