I am using Convert Query params to XML to convert from JSON to JSONX. The output of this action is stored in Jsonx_Out. I have a transform action with Jsonx_Out as input. Could anyone please help me out how I can read this context. I tried with dp:variable(' var://context/Json_Out'). This does not fetch the value.
Thanks.
Well, if it is the input context for your transform action, you can access it as you would any other XML input:
<xsl:template match="/">
<xsl:apply-templates select="/json:object"/>
</xsl:template>
(Don't forget to define the json namespace.)
You should be able to access a context with dp:variable as you described. I do notice you left out the 'x' in Jsonx_Out -- that may be your issue.
Are you sure you are getting JSONX?
Query Params outputs a XML so to get a param, eg. param1 from: http://server.com/uri?param1=HelloWorld
You'd use:
<xsl:variable name="param1">
<xsl:value-of select="/request/args/arg[#name='param1']"/>
</xsl:variable>
The XSL var "param1" would then contain "HelloWorld"
Related
I have an XQuery function to convert a group of XML files to HTML and Zip them. It runs a trasform on each file to create <entry> elements.
Starting with that function:
declare function xport:make-sources( $path as xs:string) as item()* {
for $article in collection(xmldb:encode-uri($path))
let $docnum := $article/article/div[#class = 'content']/#doc/string()
return
<entry name="{concat($docnum,'.html')}" type='text' method='store'>
{transform:transform($article, doc("/db/EIDO/data/edit/xsl/doc-html.xsl"), <parameters/>)}
</entry>
} ;
Given the input, I run the XQuery to just show me the result of the transformation ... and I see this (exactly what I would expect):
<entry name="LS01.html" type="text" method="store">
<html>
<head>
<style>
body {
font-family: Arial;
}
article img {
width:50%;
}
...
You will note the this entry and all of them have no XML Declaration at all.
But now let's put it all together and send those entries to compression. This is all inside a web application. The full XQuery is this:
xquery version "3.0";
import module namespace transform = "http://exist-db.org/xquery/transform";
declare namespace xport = "http://www.xportability.com";
declare function xport:make-sources( $path as xs:string) as item()* {
for $article in collection(xmldb:encode-uri($path))
let $docnum := $article/article/div[#class = 'content']/#doc/string()
return
<entry name="{concat($docnum,'.html')}" type='text' method='store'>
{transform:transform($article, doc("/db/EIDO/data/edit/xsl/doc-html.xsl"), <parameters/>)}
</entry>
} ;
let $path := request:get-parameter("path", "")
let $filename := request:get-parameter("filename", "")
let $col := xport:make-sources($path)
return
response:stream-binary(
xs:base64Binary(compression:zip($col,true()) ),
'application/zip',
$filename
)
Everything works, I get a ZIP file of all the documents that have been transformed to HTML from the XML.
BUT, when I look at the actually file in the ZIP, it has this:
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
The XML Declaration is not on any of the entries to ZIP. It does not exist anywhere (as it couldn't) in the list of entries. But the action of zipping them apparently is adding the declaration. I see no other reason or way. Even specifying omit-xml-declaration or changing the output type in the XSL to text or HTML makes no difference. And this is of course, because the entry list to zip is shown above and that shows the declaration is not there after the transformation.
The files in the ZIP have an added XML declaration, period.
Is there some workaround?
The XML declaration is introduced implicitly in your query when the contents of your zip-bound <entry> elements are passed to the compression:zip() function. I'd advise setting serialization options explicitly using the fn:serialize() function. Here is sample code showing how to achieve the result you describe:
xquery version "3.1";
let $node := <html><head/><body><div><h1>Hello World!</h1></div></body></html>
let $serialized := serialize($node, map { "method": "xml", "indent": true(),
"omit-xml-declaration": true() })
let $entries := <entry name="test.html" type="text" method="store">{$serialized}</entry>
let $filename := "test.zip"
return
response:stream-binary(
compression:zip($entries, true()),
'application/zip',
$filename
)
Saving this query into the database at a location like /db/apps/my-app/test.xq and calling it by pointing your web browser at http://localhost:8080/exist/apps/my-app/test.xq will cause your browser to download test.zip. Opening this zip file will reveal a test.html file absent the XML declaration:
<html>
<head/>
<body>
<div>
<h1>Hello World!</h1>
</div>
</body>
</html>
Stepping back to the fundamentals, the presence or absence of the XML declaration in XQuery is toggled via the omit-xml-declaration serialization parameter. To omit the XML declaration globally for an entire query, you can place this set of declarations in the prolog of your query:
declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "xml";
declare option output:omit-xml-declaration "yes";
Or, when serializing locally within a portion of a query, you can pass this same set of parameters to the fn:serialize function as a map (the method used in the code sample above):
fn:serialize($node, map { "method": "xml", "omit-xml-declaration": true() } )
(There is also an XML syntax for the 2nd options parameter.)
The current version of eXist (v4.0.0) and recent versions (probably since v3.6.0 or so) support all of the options above, and all versions support a somewhat more compact eXist-specific serialization facility, using the exist:serialize option expressed as a string consisting of key=value pairs:
declare option exist:serialize "method=xml omit-xml-declaration=yes";
You can set eXist's default serialization behavior in your conf.xml configuration file. The defaults in conf.xml can be overridden with the methods above. Serialization behavior over different interfaces in eXist, such as WebDAV or XML-RPC, typically respect the defaults set in conf.xml, but these defaults can be overridden on a per-interface basis; for example, see the documentation on serialization over eXist's WebDAV interface.
I am using SDL tridion 2011 SP1.
I want to get the list of keywords under given category using XSLT Mediator.
Have any one come across this situation, If yes please share your views.
But When I actually looked at the Category Item XML it does not have any info related to its keywords.
You will need to create a C# TBB to insert the category keywords into the package, and then access this as a parameter in your XSLT.
You can use a piece of c# like the following:
class GetCategoryKeywords : TemplateBase
{
public override void Transform(Engine engine, Package package)
{
Initialize(engine, package);
String webDavPathCategory = package.GetValue("CategotryWebDavPath");
Category cat = (Category)engine.GetObject(webDavPathCategory);
XmlDocument keywordsXml = new XmlDocument();
keywordsXml.LoadXml(cat.GetListKeywords().OuterXml);
Item output = package.CreateXmlDocumentItem(ContentType.Xml, keywordsXml);
package.PushItem("CategoryKeywords", output);
}
}
This will place an XML document in the package called CategoryKeywords containing the keywords. Then when you invoke the XSLT mediator, set the "Include Package Paramters" value to true, and add a parameter to the top of your XSLT as follows:
<xsl:param name="CategoryKeywords"/>
You can then loop through the new parameter as a variable performing any XPath queries on it that you desire. The following samples may help:
<xsl:variable name="URI" select="$CategoryKeywords//tcm:ListUsedItems/tcm:Item[#Title=$VALUE]/#ID" />
<xsl:for-each select="$CategoryKeywords//tcm:ListItems/tcm:Item">
Do something
<xsl:for-each>
I need to retrieve the xml attribute values in asp.net. Here i cant retrieve data from xml. Can anybody help me. Thanks in advance.
this might help you ....
Here is how my XML looks like:
<?xml version="1.0" encoding="utf-8"?>
<CategoryList>
<Category>
<MainCategory ID="1">VC++</MainCategory>
<Description>A list of VC</Description>
<Active>Yes</Active>
</Category>
</CategoryList>
add the value of the element MainCategory to the drop down list. I used the SelectNodes function to get the values and stored it while iterating through a loop. This looked like this:
XmlNodeList nodes = xmlDoc.SelectNodes("/CategoryList/Category");
for(int i=0;i<nodes.Count;i++)
{
ddlMainCategory.Items.Add(new ListItem(
nodes.Item(i).ChildNodes[0].InnerText,
nodes.Item(i).ChildNodes[0].Attributes["ID"].Value
));
}
I have a menu where I bind data through:
XmlDataSource xmlData = new XmlDataSource();
xmlData.DataFile = String.Format(#"{0}{1}\Navigation.xml", getXmlPath(), getLanguage());
xmlData.XPath = #"/Items/Item";
TopNavigation.DataSource = xmlData;
TopNavigation.DataBind();
The problem is when my xml has special characters, since I use a lot of french words.
As an alternative I tried using a stream instead and using encoding to get the special characters, with the following code:
StreamReader strm = new StreamReader(String.Format(#"{0}{1}\Navigation.xml", getXmlPath(), getLanguage()), Encoding.GetEncoding(1254));
XmlDocument xDoc = new XmlDocument();
xDoc.Load(strm);
XmlDataSource xmlData = new XmlDataSource();
xmlData.ID = "TopNav";
xmlData.Data = xDoc.InnerXml;
xmlData.XPath = #"/Items/Item";
TopNavigation.Items.Clear();
TopNavigation.DataSource = xmlData;
TopNavigation.DataBind();
The problem I'm having now is that my data doesn't refresh when I change the path where the stream gets read.
When I skip through the code it does, but not on my page.
So the thing is either, how do I get the data te be refreshed? Or (which is actually preferred) how do I get the encoding right in the first piece of code?
Help is highly apreciated!
EDIT:
I tried the CDATA solution, however i'm working with attributes so it's not possible to specify an element in an attribute, my xml:
<?xml version="1.0" encoding="utf-8" ?>
<Items Text="">
<Item Text="Actualités>"/>
<Item Text="Matériau">
<Item Text="Arsenal"/>
<Item Text="Vêtements"/>
</Item>
<Item Text="Links"/>
</Items>
Any other ideas?
Try to wrap french words with <![CDATA[....]]> tag
In this case XML will not parse your special characters
I solved my problem.
I changed the encoding of my xml file in notepad++ to UTF8 instead of ANSI (default), and it solved the problem.
Thanks for replies anyway
I want use localized strings from resources in xsl template as in aspx page, like this:
<%=GetLocalizedString("grid_numberof_claim")%>. I am trying use
<xsl:text disable-output-escaping="yes">
<![CDATA[<%=GetLocalizedString("grid_numberof_claim")%>]]>
</xsl:text>
but it is not useful.
Actually i can pass localized strings inside XML node, for example "localization". But i am looking for way to get its value in aspx style.
Using ASPX style isn't possible.
You can use XsltArgumentList to send parameters to your XSLT template, as explained here: HOW TO: Execute Parameterized XSL Transformations in .NET Applications
EDIT: Yes, you can pass arguments client-side too.
xmldoc = ... // your xml document
var xslt = new ActiveXObject("Msxml2.XSLTemplate.4.0");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.4.0");
xslDoc.async = false;
xslDoc.load("YourTemplate.xsl");
xslt.stylesheet = xslDoc;
xslProc = xslt.createProcessor();
xslProc.input = xmldoc;
xslProc.addParameter("param1", 123);
xslProc.addParameter("param2", "abc");
xslProc.transform();
But client-side leads to another solution: You can rename your XSLT file to ASPX and to use <%= %> syntax