在嵌入式 C# 代码中获取 XSLT 样式表的文件路径? (MSXML)
Get filepath of XSLT stylesheet in embedded C# code? (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 代码调用以进行条件代码执行(有效)。
我的问题:我不想硬编码文件路径 C:\Users\me\Project\images.txt
,而是想提供一个路径/文件名相对于 .xslt 文件。 .\images.txt
不起作用,它会在某些 Visual Studio 目录中查找。
是否有函数、system-属性 或任何其他方法来找出我的 .xslt 文件的绝对路径?
在一般情况下,XSLT 片段不需要具有特定位置。虽然它可以存储在文件中,但也可以是网络流,可以嵌入到 XML 文档中等等。所以在 XSLT 中没有可以查询的 "my own location" 的概念。
但是,由于我假设您使用 XslCompiledTransform
class 来执行转换,您可以在那里注入一个参数(有关详细信息,请参阅 MSDN)并将其传递给您的loadImageList
函数。
假设样式表可以通过基本 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
class 来解析相对于该基本 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('')))"/>
我使用 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 代码调用以进行条件代码执行(有效)。
我的问题:我不想硬编码文件路径 C:\Users\me\Project\images.txt
,而是想提供一个路径/文件名相对于 .xslt 文件。 .\images.txt
不起作用,它会在某些 Visual Studio 目录中查找。
是否有函数、system-属性 或任何其他方法来找出我的 .xslt 文件的绝对路径?
在一般情况下,XSLT 片段不需要具有特定位置。虽然它可以存储在文件中,但也可以是网络流,可以嵌入到 XML 文档中等等。所以在 XSLT 中没有可以查询的 "my own location" 的概念。
但是,由于我假设您使用 XslCompiledTransform
class 来执行转换,您可以在那里注入一个参数(有关详细信息,请参阅 MSDN)并将其传递给您的loadImageList
函数。
假设样式表可以通过基本 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
class 来解析相对于该基本 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('')))"/>