在嵌入式C#代码中获取XSLT样式表的文件路径? (MSXML)

时间:2017-01-24 12:37:04

标签: c# xslt visual-studio-2013 xslt-1.0 msxml

我使用XSLT + C#代码,如下所示:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                xmlns:local="urn:local"
                extension-element-prefixes="msxsl"
                exclude-result-prefixes="msxsl local">

  <msxsl:script language="CSharp" implements-prefix="local">
    <![CDATA[
      public string imageList;

      public bool loadImageList()
      {
        imageList = System.IO.File.ReadAllText("C:\\Users\\me\\Project\\images.txt");
        return true;
      }

      public bool inImageList(string str)
      {
        return imageList.Contains("\r\n" + str + "\r\n");
      }
    ]]>
  </msxsl:script>

  <xsl:variable name="loadImageList" select="local:loadImageList()"/>

  <xsl:template match="/">
    <xsl:apply-templates select="recordList/record"/>
  </xsl:template>

  <xsl:template match="record">
    <xsl:if test="inImageList(@id) = true()">
      <image>
        <xsl:value-of select="concat(@id, '.jpg')"/>
      </image>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

在C#中,加载外部文件,内容存储在变量中。如果该文本中包含某个值,则函数inImageList()提供测试方法。它由XSLT代码调用,用于条件代码执行(工作)。

我的问题:我希望提供相对于.xslt文件的路径/文件名,而不是对文件路径C:\\Users\\me\\Project\\images.txt进行硬编码。 .\\images.txt不起作用,它在某些Visual Studio目录中查找。

是否有函数,系统属性或任何其他方法来查找my .xslt文件的绝对路径?

2 个答案:

答案 0 :(得分:2)

假设样式表可以以基本URI可用的方式加载,您可以按如下方式执行:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl mf"
                xmlns:mf="http://example.com/mf"
>
    <xsl:output method="xml" indent="yes"/>

  <msxsl:script language="C#" implements-prefix="mf">
    public string GetBaseUri(XPathNavigator node) {
      return node.BaseURI;
    }

    public string GetFilePath(string baseUri, string fileName) {
      return new Uri(new Uri(baseUri), fileName).LocalPath;
    }
  </msxsl:script>


  <xsl:template match="/">
    <xsl:value-of select="mf:GetFilePath(mf:GetBaseUri(document('')), 'textInput.txt')"/>

  </xsl:template>
</xsl:stylesheet>

请注意,这需要启用脚本以及document函数,然后可以使用XSLT document('')内部来获取样式表的树表示,然后可以将其传递给一个带XPathNavigator的扩展函数,允许您读出BaseURI属性,一旦有了这个属性,就可以使用Uri类来解析相对于该基URI的文件名和然后,您可以获得该URI的LocalPath表示,然后您可以使用该表示来加载文本文件。

因此,在代码的上下文中,您可以使用

    

  public bool loadImageList(string baseUri)
  {
    imageList = System.IO.File.ReadAllText(GetFilePath(baseUri, "images.txt"));
    return true;
  }

  public bool inImageList(string str)
  {
    return imageList.Contains("\r\n" + str + "\r\n");
  }

    public string GetBaseUri(XPathNavigator node) {
      return node.BaseURI;
    }

    public string GetFilePath(string baseUri, string fileName) {
      return new Uri(new Uri(baseUri), fileName).LocalPath;
    }
]]>

 <xsl:variable name="loadImageList" select="local:loadImageList(local:GetBaseUri(document('')))"/>

答案 1 :(得分:0)

在一般情况下,XSLT片段不需要具有特定位置。虽然它可以存储在文件中,但它也可以是网络流,它可以嵌入XML文档中等等。因此,在XSLT中,没有“我自己的位置”的概念,您可以查询。

但是,由于我假设您使用XslCompiledTransform类来执行转换,您可以在那里注入一个参数(有关详细信息,请参阅MSDN)并将其传递给loadImageList函数