XQuery - pass HTML in a parameter to XSLT - xslt

In XQuery 3.1 I have a function which outputs a snippet of HTML. This function:
declare function document:doc-citation($currentdoc as xs:string)
{
let $citation :=
(<div>
<p class="cite-document">To cite this document: </span>
<p>{common:cite-doc($currentdoc,"html")}</p>
</div>)
return $citation
};
Outputs this:
<div>
<p class="cite-document"><span>To cite this document: </span></p>
<p><span>Fooname. <i>Foo title</i>. Foopublisher. 2018.</span></p>
</div>
Now I want to pass this complete HTML into a parameter for XSLT. So in an XQuery function transform:transform() that otherwise works fine for the other (string) parameters, I attempt to pass the HTML like so:
<param name="paramCitation" value="{document:doc-citation($mydoc)}"/>
Which XSLT 2.0 should pickup through:
<xsl:param name="paramCitation"/>
And output the HTML through this XSLT:
<xsl:value-of select="paramCitation"/>
I've never tried to pass HTML through an XQuery/XSLT parameter before.
I think somewhere I'm not handling the HTML correctly in the XQuery parameter, or not handling the parameter output correctly in XSLT (HTML/string conversion problems)?
Thanks in advance.

Related

How to process HTML entities in XSLT

I am trying to transform XHTML that contains the entity. Saxon complains that the entity is not defined. How can I define it?
Is it possible to add the entity definition at the beginning of the stylesheet? As suggested
here:
http://s-n-ushakov.blogspot.com/2011/09/xslt-entities-java-xalan.html
or here:
Using an HTML entity in XSLT (e.g. )
My puny attempt, ignored by Saxon, was to add the following to the beginning of the XSLT:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE stylesheet [
<!ENTITY nbsp " ">
]>
I am using Saxon 9.9 PE.
The HTML I am trying to transform is a complete document, not just a fragment.
One possibility is to pass the URL of the XHTML to the XSLT as a parameter, which would read the XHTML as text using the unparsed-text() function, expand the entity reference using the replace() function, and parse the result using the parse-xml() function. e.g.
<xsl:template name="xsl:initial-template">
<xsl:param name="source"/>
<xsl:apply-templates select="
$source
=> unparsed-text()
=> replace('&nbsp;', '&#x000A0;')
=> parse-xml()
"/>
</xsl:template>
If the input document contains an entity reference that isn't declared in the DOCTYPE declaration, then it isn't a well-formed XML document, and therefore it isn't a well-formed XHTML document; and if it isn't well-formed, then Saxon can't handle it.
It would be best to look at the processing workflow that generated this ill-formed document and fix it so the documents it produces are well-formed.
If you can't do that, then you might be able to parse it as HTML. Saxon has an extension function saxon:parse-html(); or if your application is in Java then you could create a SAXSource that uses validator.nu as its XMLReader.
You should consider using the tool Tidy and convert html files into xhtml. It corrects all such things.
Just run tidy with the argument -asxml.

disable-output-escaping twice in a DVWP using XSLT

I have a custom list. That custom list has a plain text milti-line field. In it the user will enter HTML, like <br>hi</br>;
I want to render that HTML in my DVWP using XSLT.
<xsl:value-of select="#Field_Name" disable-output-escaping="no" /> outputs <b>hi</b>
<xsl:value-of select="#Field_Name" disable-output-escaping="Yes" /> outputs <b>hi</b>
Anyway I can make it render the actual HTML? So I want it to output hi.
Change your custom field from Plain text to Rich text type because plain text assume <b>hi</b> as part of data. If you change your field type can see html formated text in your browser with same xslt code like hi.

How to read namespace declarations using XSLT?

I have to trasform the raw response of any OData feed (ATOM) in the form of a tree with expandable/collapsable nodes. For this purpose I am converting the raw response into HTML using XSLT transformation.
The problem is that response from some services have the feed element with namespace declarations as attributes. (eg: feed xmlns:d= ..., xmlns:m= ...).In my final output these namespace declarations are not displayed.
The XSLT processor ignores them while processing the attributes.(I am using the XPath expression "#*".) Is there a way to extract them using XSLT and display the namespace declaration content as-is in the trasformed output ?
Note that I get to know about these namespace declaration attributes at runtime in the OData response. I have no information before the query executes.
UPDATE:
Input : (RAW XML Entry)
<?xml version="1.0" encoding="utf-8"?><entry xml:base="http://services.odata.org/Northwind/Northwind.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><id>http://services.odata.org/Northwind/Northwind.svc/Regions(1)</id><category term="NorthwindModel.Region" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /><link rel="edit" title="Region" href="Regions(1)" /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Territories" type="application/atom+xml;type=feed" title="Territories" href="Regions(1)/Territories" /><title /><updated>2014-03-17T10:24:14Z</updated><author><name /></author><content type="application/xml"><m:properties><d:RegionID m:type="Edm.Int32">1</d:RegionID><d:RegionDescription xml:space="preserve">Eastern </d:RegionDescription></m:properties></content></entry>
Desired Output: (The same ATOM entry,as a XML tree, pretty printed with expandable/collapsable nodes)
-<entry xml:base="http://services.odata.org/Northwind/Northwind.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
-<id>
http://services.odata.org/Northwind/Northwind.svc/Regions(1)
</id>
<category term="NorthwindModel.Region" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link rel="edit" title="Region" href= "Regions(1)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Territories" type="application/atom+xml;type=feed" title="Territories" href= "Regions(1)/Territories" />
<title/>
<updated>2014-03-17T10:06:25Z</updated>
-<author>
<name/>
</author>
-<content type="application/xml">
-<m:properties>
<d:RegionID m:type="Edm.Int32">1</d:RegionID>
<d:RegionDescription xml:space="preserve">Eastern </d:RegionDescription>
</m:properties>
</content>
</entry>
Output which I am getting.
-<entry xml:base="http://services.odata.org/Northwind/Northwind.svc/">
-<id>
http://services.odata.org/Northwind/Northwind.svc/Regions(1)
</id>
<category term="NorthwindModel.Region" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<link rel="edit" title="Region" href= "Regions(1)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Territories" type="application/atom+xml;type=feed" title="Territories" href= "Regions(1)/Territories" />
<title/>
<updated>2014-03-17T10:06:25Z</updated>
-<author>
<name/>
</author>
-<content type="application/xml">
-<m:properties>
<d:RegionID m:type="Edm.Int32">1</d:RegionID>
<d:RegionDescription xml:space="preserve">Eastern </d:RegionDescription>
</m:properties>
</content>
</entry>
Please note the missing name space declarations in the output's "entry" root element.
The output is a HTML which displays pretty-printed xml, with expandable/collapsable nodes and since it should display the data as-is, namespace declarations are required to be displayed in the output HTML.
Clicking on the "-" symbols collapses the nodes.
If a declaration is already in scope (remember, namespace bindings are inherited to children), it will not need to be redeclared and most XML serializers will not generate it. You haven't shown us an example yet, but I'd bet your output is fine as it is.
Namespace declarations in your source XML appear in the XPath data model as namespace nodes (not attribute nodes).
You need to make clear what you want to do with the namespaces. You're saying that you are generating HTML, but you also say you want to copy the namespaces to the output. That seems inconsistent. Show us you input and desired output.
I haven't managed to spot the difference between your actual output and your desired output (never was very good at "spot the ball" competitions), but from your revised description of the problem it sounds as if you should be using the namespace axis to find the in-scope namespaces for an element (in the same way as you are currently using the attribute axis).
The only tricky part is that the namespace axis will give you all the namespaces for an element and you probably only want to show those that are different from the namespaces of the parent element.
The details depend on whether you are using XSLT 1.0 or 2.0 - you need to tell us!

How to select a property of a macro parameter in XSLT?

This is a very basic XSL question and I am just getting started with the topic in the context of Umbraco:
I've defined a macro with a XSLT file. The macro has a parameter of type 'ContentPicker'. What I want to do with the macro, is to render the picked content in a certain way. The relevant bit of my XSLT file is this:
<xsl:param name="source" select="/macro/BlogPostSource"/>
<xsl:template match="/">
<div>
<xsl:value-of select="$source/blogPostIntroduction"/>
</div>
I define a parameter, which is set to the parameter of the macro (this works). Now I simply want to render the property blogPostIntroduction which is a generic property on the picked content. This doesn't work. If I use
<xsl:value-of select="$source"/>
the ID of the content is rendered.
Question A: How do I select fields of the selected content?
Question B: Is my idea correct in general or am I missing a better way to do what I need, rather than using macros and XSLT?

Xslt expression [.=

I have here a small XSLT code, but I don't understand one of the expressions and also one of my added values doesn't work.
Here is what i have:
<xsl:choose>
<xsl:when test="contentclass[. = 'STS_ListItem_DocumentLibrary'] and {imageurl/#imageurldescription} = 'Web Page'">
<div class="srch-Icon" id="{concat($currentId,'_Icon')}">
<img align="absmiddle" src="/_layouts/images/itdl.png" border="0" alt="Document Library" />
</div>
</xsl:when>
<xsl:otherwise>
<div class="srch-Icon" id="{concat($currentId,'_Icon')}">
<img align="absmiddle" src="{imageurl}" border="0" alt="{imageurl/#imageurldescription}" />
</div>
</xsl:otherwise>
Basically as you see, what does this expression means => "[.="?
And secondly this doenst work, anyone know why?
{imageurl/#imageurldescription} = 'Web Page'
Why the problem can exist?
The value exists 100% as in default call it works (in otherwise i do get value there)
{ } around an expression in an attribute on a normal element will make the XSLT engine evaluate it, instead of treat it as text. In most attributes on control-elements (<xsl:...), the curly braces are not needed, and there will be a syntax error if you include them.
The contentclass[. = 'STS_ListItem_DocumentLibrary'] part means: Match all child contentclass elements whenever their content is "STS_ListItem_DocumentLibrary". It is equivalent to: contentclass = 'STS_ListItem_DocumentLibrary'
Read more:
XSLT 1.0: Attribute Value Templates