I'm trying to get content from another XML file in the same directory as my XML file. However, I don't know how to get the uri of the source XML. The XSLT keeps relating to its own directory.
How can I get the URI of the source XML?
I would recommend document-uri() rather than base-uri(). It will usually be the same, but base-uri() is affected by the xml:base attribute and by use of XML external entities, while document-uri() is not.
You can use the base-uri() function:
<!-- your external XML -->
<xsl:variable name="doc" select="document('http://www.xyz.com./path/your-doc.xml')"/>
<!-- the base URI of your external XML -->
<xsl:variable name="doc-base-uri" select="base-uri($doc)"/>
I found an answer that worked for me.
I got it using base-uri(.).
Related
I just wanted to generate a documentation of a schema with xs3p.
The problem is, as far as I understand it, that the schema is split into several files and that xs3p did not process the include-tags of the master file: The result is a documentation containing only the root element.
What did I do exactly?
I unzipped the xs3p-download into a certain directory
I copied all schema files into the directory
I called saxonb-xslt master.xsd xs3p.xsl >doku.html (under Ubuntu Trusty, if that matters)
Can you give me any help? I assume, there are two lines to solve the problem:
Making xs3p process the include-tags
Integrating all xsd-files into a single one — how would this work?
Thank you in advance!
You have to set the following xsl:param in xs3p.xsl :
<!-- If 'true', searches 'included' schemas for schema components
when generating links and XML Instance Representation tables. -->
<xsl:param name="searchIncludedSchemas">true</xsl:param>
<!-- If 'true', searches 'imported' schemas for schema components
when generating links and XML Instance Representation tables. -->
<xsl:param name="searchImportedSchemas">true</xsl:param>
<!-- File containing the mapping from file locations of external
(e.g. included, imported, refined) schemas to file locations
of their XHTML documentation. -->
<xsl:param name="linksFile">xs3p_links.xml</xsl:param>
Your included/imported schemas must have been previously transformed into a my_transformed_included_schema.html file, and you need to define a xs3p_links.xml file in order to assign some imported/included schema to theirs location such as :
<?xml version="1.0"?>
<links xmlns="http://titanium.dstc.edu.au/xml/xs3p">
<schema file-location="my-included-schema.xsd" docfile-location="./my_transformed_included_schema.html"/>
</links>
Hope that'll help !
I loaded an XML file via the "Import XML definition" and everything worked fine. But the XML needs the following added to it
Here is my question,
I just have the XML but not the xsd.
How do I add the xmlns and xsi string into the root node?
For the elements, how do I add the tag like 'common' and 'udf' before the column name like common:abbreviation or udf:name or udf:value?
Basically is there an easy and quick way to do this? Do I need to reimport the files with new xsd?
Thanks
<MyRoot
xmlns:udf="http://www.url.com/xx/XXXX/type1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:common="http://www.url.com/xx/XXXX/common"
xmlns="http://www.url.com/ws/v410/NewPerson"
xsi:schemaLocation="http://www.url.com/xx/XXXX/NewPerson NewPerson.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<common:ID>NNNNNNNNNN</common:ID>
<UDF>
<udf:name>Name Content</udf:name>
<udf:value></udf:value>
</UDF>
</MyRoot>
I've written a post about adding ports to XML transformation. See if this helps: http://powercenternotes.blogspot.com/2013/03/adding-port-to-existing-xml-parser.html
I'm new at XSLT. I want to create a hyperlink using XSLT. Should look like this:
Document
Document is the link and upon clicking this, download of a file should begin.
Any ideas? :)
Thanks
There's no such thing as a hyperlink in XSLT or XML. If you're generating HTML with your XSLT, then you just need to output the appropriate elements and attributes, which you can do literally if you want, e.g.
<xsl:template match="somethingthatgeneratesalink">
This is a link to example.com
</xsl:template>
I have a bunch of XML files with a fixed, country-based naming schema: report_en.xml, report_de.xml, report_fr.xml, etc. Now I want to write an XSLT style sheet that reads each of these files via the document() XPath function, extracts some values and generates one XML files with a summary. My question is: How can I iterate over the source files without knowing the exact names of the files I will process?
At the moment I'm planning to generate an auxiliary XML file that holds all the file names and use the auxiliary XML file in my stylesheet to iterate. The the file list will be generated with a small PHP or bash script. Are there better alternatives?
I am aware of XProc, but investing much time into it is not an option for me at the moment. Maybe someone can post an XProc solution. Preferably the solution includes workflow steps where the reports are downloaded as HTML and tidied up :)
I will be using Saxon as my XSLT processor, so if there are Saxon-specific extensions I can use, these would also be OK.
You can use the standard XPath 2.x collection() function, as implemented in Saxon 9.x
The Saxon implementation allows a search pattern to be used in the string-Uri argument of the function, thus you may be able to specify after the path of the directory a pattern for any filename starting with report_ then having two other characters, then ending with .xml.
Example:
This XPath expression:
collection('file:///c:/?select=report_*.xml')
selects the document nodes of every XML document that resides in c:\ in a file with name starting with report_ then having a 0 or more characters, then ending with .xml.
The answer by Dimitre looks like the quickest solution in your case. But since you asked, here an XProc alternative:
<p:declare-step version="1.0" xmlns:p="http://www.w3.org/ns/xproc" xmlns:c="http://www.w3.org/ns/xproc-step" exclude-inline-prefixes="#all" name="main">
<!-- create context for p:variable with base-uri pointing to the location of this file -->
<p:input port="source"><p:inline><x/></p:inline></p:input>
<!-- any params passed in from outside get passed through to p:xslt automatically! -->
<p:input port="parameters" kind="parameter"/>
<!-- configuration options for steering input and output -->
<p:option name="input-dir" select="'./'"/>
<p:option name="input-filter" select="'^report_.*\.xml$'"/>
<p:option name="output-dir" select="'./'"/>
<!-- resolve any path to base uri of this file, to make sure they are absolute -->
<p:variable name="abs-input-dir" select="resolve-uri($input-dir, base-uri(/))"/>
<p:variable name="abs-output-dir" select="resolve-uri($output-dir, base-uri(/))"/>
<!-- first step: get list of all files in input-dir -->
<p:directory-list>
<p:with-option name="path" select="$abs-input-dir"/>
</p:directory-list>
<!-- iterate over each file to load it -->
<p:for-each>
<p:iteration-source select="//c:file[matches(#name, $input-filter)]"/>
<p:load>
<p:with-option name="href" select="resolve-uri(/c:file/#name, $abs-input-dir)"/>
</p:load>
</p:for-each>
<!-- wrap all files in a reports element to be able to hand it in to the xslt as a single input document -->
<p:wrap-sequence wrapper="reports"/>
<!-- apply the xslt (stylesheet is loaded below) -->
<p:xslt>
<p:input port="stylesheet">
<p:pipe step="style" port="result"/>
</p:input>
</p:xslt>
<!-- store the result in the output dir -->
<p:store>
<p:with-option name="href" select="resolve-uri('merged-reports.xml', $abs-output-dir)"/>
</p:store>
<!-- loading of the stylesheet.. -->
<p:load href="process-reports.xsl" name="style"/>
</p:declare-step>
Store the above as process-reports.xpl for instance. You can run it with XMLCalabash (http://xmlcalabash.com/download/). You can run it like this:
java -jar calabash.jar process-reports.xpl input-dir=./ output-dir=./
The above code assumes a process-reports.xsl that takes one documents that wraps all reports, and does a bit of processing on it. You could do processing in pure XProc as well, but you might prefer it this way.
You could also move the p:xslt step up to within the p:for-each (below the p:load), that would cause the xslt to be applied to each report individually.
Good luck!
I have 3 XSL files which have paths in them to something like C:\templates\Test\file.pdf
This path isn't always going to be the same and rather than having it hard coded in the XSL, I'd like it so that the path C:\templates\test\ is replaced with a tag [BASEPATH] and when I read in the xsl file into the XSLTransform object (yes I know it's been deprecated, I may move over to the XSLCompiledTransform at the same time), I'd like the tag [BASEPATH] to be replaced with the absolute file path of the web folder (or Server.MapPath("~") seeing as it is in .net)
I thought I may be able to make an XSLLoader aspx page which takes the name of the XSL file through the querystring and then returns the XSL file via xml content-type. When I try this, I get a 503 error though so I'm not sure if you can pass urls like this into the XSLTransform.Load method.
Any ideas what to do?
Have you looked at XSL parameters?
<xsl:param name="basepath" select="'C:\Users\Graeme\'" />
<xsl:value-of select="document(concat($basepath, 'test.pdf'))" />
Then, most decent XSLT engines have a way to set a root level parameter from outside.