XSL:从 VBS 脚本获取 XML 对象
XSL: Getting XML Object from VBS Script
我一直在努力解决以下问题:
- 我想将 XML 从 C# 传递到 XSL 文件中嵌入的 VBS 脚本(完成 - 我将其作为字符串发送),
- 将此 XML 传递给 XSL 标记 <xsl:for-each>
- 遍历此 XML
的所有子元素
c#:
namespace EcodMappingUtils
{
[ComVisible(true)]
[Transaction(TransactionOption.RequiresNew)]
[assembly: ApplicationName("EcodMappingUtilsProxy")]
[assembly: ApplicationActivation(ActivationOption.Library)]
public class Proxy : ServicedComponent
{
public object CatalogGet(string p_SrcAliasValue, string p_DestAliasValue, string p_BusinessType_Type)
{
return "<?xml version='1.0' encoding='UTF-8' standalone='yes'?><root><b1><content>abc</content></b1> <b2><content>def</content></b2></root>";
}
}
}
xsl 中的 vbs:
<msxsl:script language="VBScript" implements-prefix="user">
Function CatalogGet(p_SrcAliasValue, p_DestAliasValue, p_BusinessType_Type)
Dim obj
obj = CreateObject("EcodMappingUtils.Proxy")
CatalogGet = obj.CatalogGet(p_SrcAliasValue, p_DestAliasValue, p_BusinessType_Type)
End Function
</msxml:script>
当我尝试遍历这个 XML:
<xsl:for-each select="user:CatalogGet('', '', '')">
</xsl:for-each>
我得到一个错误,表达式必须 return 一组节点。
我尝试在 VBS 中将字符串转换为 XMLDOM.Document,但在从 COM 对象转换为 CLR 时出现错误。
我该怎么办?
编辑:
XSL 转换:
var myXslTrans = new XslCompiledTransform(true);
XsltSettings settings = new XsltSettings();
settings.EnableScript = true;
settings.EnableDocumentFunction = true;
myXslTrans.Load(@"../../test.xslt", settings, new XmlUrlResolver());
myXslTrans.Transform("../../file.xml", "../../file_out.xml");
如果 XSLT 处理器是 .NET 的 XslCompiledTransform
,那么您的 "script" 不是 VBScript,而是 VB.NET 即时编译为 .NET 代码。你需要 return 的数据类型是 XPathNavigator
所以例如
Dim doc As XPathDocument
Using sr As New StringReader("<root><b1><content>abc</content></b1> <b2><content>def</content></b2></root>")
doc = New XPathDocument(sr);
End Using
Return doc.CreateNavigator()
会将字符串解析为 XML,创建一个 XPathDocument 和 return 一个选择根节点的 XPathNavigator XSLT/XPath。然后您的 XSLT 可以使用例如<xsl:for-each select="user:CatalogGet('', '', '')//content">...</xsl:for-each>
。有关 XSLT 和 .NET 之间类型映射的详细信息,请参阅 https://msdn.microsoft.com/en-us/library/wxaw5z5e%28v=vs.110%29.aspx。
我一直在努力解决以下问题:
- 我想将 XML 从 C# 传递到 XSL 文件中嵌入的 VBS 脚本(完成 - 我将其作为字符串发送),
- 将此 XML 传递给 XSL 标记 <xsl:for-each>
- 遍历此 XML
c#:
namespace EcodMappingUtils
{
[ComVisible(true)]
[Transaction(TransactionOption.RequiresNew)]
[assembly: ApplicationName("EcodMappingUtilsProxy")]
[assembly: ApplicationActivation(ActivationOption.Library)]
public class Proxy : ServicedComponent
{
public object CatalogGet(string p_SrcAliasValue, string p_DestAliasValue, string p_BusinessType_Type)
{
return "<?xml version='1.0' encoding='UTF-8' standalone='yes'?><root><b1><content>abc</content></b1> <b2><content>def</content></b2></root>";
}
}
}
xsl 中的 vbs:
<msxsl:script language="VBScript" implements-prefix="user">
Function CatalogGet(p_SrcAliasValue, p_DestAliasValue, p_BusinessType_Type)
Dim obj
obj = CreateObject("EcodMappingUtils.Proxy")
CatalogGet = obj.CatalogGet(p_SrcAliasValue, p_DestAliasValue, p_BusinessType_Type)
End Function
</msxml:script>
当我尝试遍历这个 XML:
<xsl:for-each select="user:CatalogGet('', '', '')">
</xsl:for-each>
我得到一个错误,表达式必须 return 一组节点。 我尝试在 VBS 中将字符串转换为 XMLDOM.Document,但在从 COM 对象转换为 CLR 时出现错误。
我该怎么办?
编辑:
XSL 转换:
var myXslTrans = new XslCompiledTransform(true);
XsltSettings settings = new XsltSettings();
settings.EnableScript = true;
settings.EnableDocumentFunction = true;
myXslTrans.Load(@"../../test.xslt", settings, new XmlUrlResolver());
myXslTrans.Transform("../../file.xml", "../../file_out.xml");
如果 XSLT 处理器是 .NET 的 XslCompiledTransform
,那么您的 "script" 不是 VBScript,而是 VB.NET 即时编译为 .NET 代码。你需要 return 的数据类型是 XPathNavigator
所以例如
Dim doc As XPathDocument
Using sr As New StringReader("<root><b1><content>abc</content></b1> <b2><content>def</content></b2></root>")
doc = New XPathDocument(sr);
End Using
Return doc.CreateNavigator()
会将字符串解析为 XML,创建一个 XPathDocument 和 return 一个选择根节点的 XPathNavigator XSLT/XPath。然后您的 XSLT 可以使用例如<xsl:for-each select="user:CatalogGet('', '', '')//content">...</xsl:for-each>
。有关 XSLT 和 .NET 之间类型映射的详细信息,请参阅 https://msdn.microsoft.com/en-us/library/wxaw5z5e%28v=vs.110%29.aspx。