简体   繁体   中英

How to get an absolute path to the directory of the XSL file?

My Schema.xsd file is located in the same directory with the .xsl file. In the .xsl file I would like to generate a link to Schema.xsl in the generated output. The generated output is located in different directories. Currently I do it like this:

   <xsl:template match="/">
     <root version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:noNamespaceSchemaLocation="../../../Schema.xsd">
     <!-- . . . -->

However this forces the generated output to be located 3 levels under the directory of Schema.xsd . I would like to generate an absolute path to the schema in the output, so the output could be located anywhere.

Update. I use XSLT 1.0 ( XslCompiledTransform implementation in .NET Framework 4.5).

XSLT 2.0 Solution

Use the XPath 2.0 function, resolve-uri() :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"
              omit-xml-declaration="yes"
              encoding="UTF-8"/>
  <xsl:template match="/">
    <root version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="{concat(resolve-uri('.'), 'Schema.xsd')}">
    </root>
  </xsl:template>

</xsl:stylesheet>

Yields, without parameter passing and regardless of the input XML:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      version="1.0"
      xsi:noNamespaceSchemaLocation="file:/c:/path/to/XSLT/file/Schema.xsd"/>

This is a sketch of how to do it (also see Passing parameters to XSLT Stylesheet via .NET ).

In your C# code you need to define and use a parameter list:

XsltArgumentList argsList = new XsltArgumentList();
argsList.AddParam("SchemaLocation","","<SOME_PATH_TO_XSD_FILE>");

XslCompiledTransform transform = new XslCompiledTransform();
transform.Load("<SOME_PATH_TO_XSLT_FILE>");

using (StreamWriter sw = new StreamWriter("<SOME_PATH_TO_OUTPUT_XML>"))
{
    transform.Transform("<SOME_PATH_TO_INPUT_XML>", argsList, sw);
} 

Your XSLT could be enhanced like this:

...
<xsl:param name="SchemaLocation"/> <!-- this more or less at the top of your XSLT! -->
...

<xsl:template match="/">
   <root version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="{$SchemaLocation}">
   ...
   ...
</xsl:template>
....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM