有没有办法调试由自定义xmlurlresolver从数据库加载的xslt文档,或者有人知道下面的错误消息是关于什么的?
我有一个导入公共xslt文档的xslt样式表:
<xsl:import href="db://common.hist.org"/>
XmlResolver处理,但我得到一个错误:xsl:import引用的公共xslt文档包含一些公共xslt模板,每个模板都有一个唯一的名称。XslCompiledTransform实例时启用调试,但不知何故,无法“单步执行”基于数据库的xslt。_xslHtmlOutput = new XslCompiledTransform(XSLT_DEBUG);
public class XmlDBResolver : XmlUrlResolver
{
private IDictionary<string,string> GetUriComponents(String uri)
{
bool useXmlPre = false;
uri = uri.Replace("db://", "");
useXmlPre = uri.StartsWith("xml/");
uri = uri.Replace("xml/", "");
IDictionary<string, string> dict = new Dictionary<string, string>();
string app = null, area = null, subArea = null;
if (!String.IsNullOrWhiteSpace(uri))
{
string[] components = uri.Split('.');
if (components == null)
throw new Exception("Invalid Xslt URI");
switch (components.Count())
{
case 3:
app = components[0];
break;
case 4:
area = components[0];
app = components[1];
break;
case 5:
subArea = components[0];
area = components[1];
app = components[2];
break;
default:
throw new Exception("Invalid Xslt URI");
}
dict.Add("application", app);
dict.Add("area", area);
dict.Add("subArea", subArea);
dict.Add("xmlPreTransform", String.Format("{0}", useXmlPre));
}
return dict;
}
public override System.Net.ICredentials Credentials
{
set { /* TODO: check if we need credentials */ }
}
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
/*
* db://<app>.hist.org
* db://<area>.<app>.hist.org
* db://<subArea>.<area>.<app>.hist.org
*
* */
Tracing.TraceHelper.WriteLine(String.Format("GetEntity {0}", absoluteUri));
XmlReader reader = null;
switch (absoluteUri.Scheme)
{
case "db":
string origString = absoluteUri.OriginalString;
IDictionary<string, string> xsltDict = GetUriComponents(origString);
if(String.IsNullOrWhiteSpace(xsltDict["area"]))
{
reader = DatabaseServiceFactory.DatabaseService.GetApplicationXslt(xsltDict["application"]);
}
else if (!String.IsNullOrWhiteSpace(xsltDict["area"]) && String.IsNullOrWhiteSpace(xsltDict["subArea"]) && !Boolean.Parse(xsltDict["xmlPreTransform"]))
{
reader = DatabaseServiceFactory.DatabaseService.GetAreaXslt(xsltDict["application"], xsltDict["area"]);
}
else if (!String.IsNullOrWhiteSpace(xsltDict["area"]) && !String.IsNullOrWhiteSpace(xsltDict["subArea"]))
{
if(Boolean.Parse(xsltDict["xmlPreTransform"]))
reader = DatabaseServiceFactory.DatabaseService.GetSubareaXmlPreTransformXslt(xsltDict["application"], xsltDict["area"], xsltDict["subArea"]);
else
reader = DatabaseServiceFactory.DatabaseService.GetSubareaXslt(xsltDict["application"], xsltDict["area"], xsltDict["subArea"]);
}
return reader;
default:
return base.GetEntity(absoluteUri, role, ofObjectToReturn);
}
}
public interface IDatabaseService
{
...
XmlReader GetApplicationXslt(String applicationName);
XmlReader GetAreaXslt(String applicationName, String areaName);
XmlReader GetSubareaXslt(String applicationName, String areaName, String subAreaName);
XmlReader GetSubareaXmlPreTransformXslt(String applicationName, String areaName, String subAreaName);
}
最佳答案
简短回答:
您的IDatabaseService接口方法返回XmlReader对象。在构造这些函数时,请确保将abaseUri传递给构造函数;例如:
public XmlReader GetApplicationXslt(string applicationName)
{
…
var baseUri = string.Format("db://{0}.hist.org", applicationName);
return XmlReader.Create(input: …,
settings: …,
baseUri: baseUri); // <-- this one is important!
}
db://…路径)XmlDbResolver来处理db://导入方案IDatabaseService的形式实现数据库访问代码,它支持XmlDbResolverXmlResolver类和/或IDatabaseService实现中。由于您尚未显示后者的代码,因此我们无法在不进行猜测的情况下调试您的代码。XmlDbResolver创建了一个模拟项目(下面是完整的描述)。我无法重现错误,因此我怀疑是您的IDatabaseService实现导致了错误。git clone https://gist.github.com/fbbd5e7319bd6c281c50b4ebb1cee1f9.git)克隆this Gist,然后签出第二次提交git checkout d00629,来检索该项目)。我将在下面更详细地描述每个解决方案项。SqlServerDatabase.mdf、TestInput.xml和.xslt项目项的copy to output directory属性都应设置为always。)App.config中的连接字符串完成的;请参见下文。)Program.cs和CommonHistOrg.xslt)。<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="SqlServerDatabase"
connectionString="Data Source=.\SQLEXPRESS;
AttachDbFilename=|DataDirectory|\SqlServerDatabase.mdf;
Integrated Security=True;
User Instance=True"
/>
</connectionStrings>
</configuration>
IDatabaseService接口的定义,我在这里不再重复。IDatabaseService的类。它将数据读/写到上述数据库:using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.IO;
using System.Xml;
class SqlServerDatabaseService : IDatabaseService
{
// creates a connection based on connection string from App.config:
SqlConnection CreateConnection()
{
return new SqlConnection(connectionString: ConfigurationManager.ConnectionStrings["SqlServerDatabase"].ConnectionString);
}
// stores an XML document into the 'ApplicationDocuments' table:
public void StoreApplicationDocument(string applicationName, XmlReader document)
{
using (var connection = CreateConnection())
{
SqlCommand command = connection.CreateCommand();
command.CommandText = "INSERT INTO ApplicationDocuments (ApplicationName, Document) VALUES (@applicationName, @document)";
command.Parameters.Add(new SqlParameter("@applicationName", applicationName));
command.Parameters.Add(new SqlParameter("@document", new SqlXml(document)));
// ^^^^^^^^^^^^^^^^^^^^
connection.Open();
int numberOfRowsInserted = command.ExecuteNonQuery();
connection.Close();
}
}
// reads an XML document from the 'ApplicationDocuments' table:
public XmlReader GetApplicationXslt(string applicationName)
{
using (var connection = CreateConnection())
{
SqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT Document FROM ApplicationDocuments WHERE ApplicationName = @applicationName";
command.Parameters.Add(new SqlParameter("@applicationName", applicationName));
connection.Open();
var plainXml = (string)command.ExecuteScalar();
connection.Close();
if (plainXml != null)
{
return XmlReader.Create(new StringReader(plainXml));
}
else
{
throw new KeyNotFoundException(message: string.Format("Database does not contain a application document named '{0}'.", applicationName));
}
}
}
… // (all other methods throw a NotImplementedException)
}
XmlDbResolver类,与您的XmlDBResolver类相同,但有两个更改:IDatabaseService对象。这是用来代替DatabaseServiceFactory.DatabaseService。Tracing.TraceHelper.WriteLine的呼叫。db://common.hist.org样式表,将在运行时放入数据库(请参见下面的Program.cs):<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Foo">
<Bar/>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="db://common.hist.org"/>
</xsl:stylesheet>
db://common.hist.org转换的xml测试输入文档:<?xml version="1.0" encoding="utf-8" ?>
<Foo/>
using System;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
class Program
{
static void Main(string[] args)
{
var databaseService = new SqlServerDatabaseService();
// put CommonHistOrg.xslt into the 'ApplicationDocuments' database table:
databaseService.StoreApplicationDocument(
applicationName: "common",
document: XmlReader.Create("CommonHistOrg.xslt"));
// load the XSLT stylesheet:
var xslt = new XslCompiledTransform();
xslt.Load(@"TestStylesheet.xslt",
settings: XsltSettings.Default,
stylesheetResolver: new XmlDbResolver(databaseService));
// load the XML test input:
var input = XmlReader.Create("TestInput.xml");
// transform the test input and store the result in 'output':
var output = new StringBuilder();
xslt.Transform(input, XmlWriter.Create(output));
// display the transformed output:
Console.WriteLine(output.ToString());
Console.ReadLine();
}
}
TestStylesheet.xslt的xml文档,这就是<Bar/>样式表从测试输入中为匹配的db://common.hist.org元素输出的内容。<Foo/>方法中插入以下语句:databaseService.StoreApplicationDocument(
applicationName: "test",
document: XmlReader.Create("TestStylesheet.xslt"));
xslt.Load(@"TestStylesheet.xslt", …);
xslt.Load(@"db://test.hist.org", …);
Main列具有Document类型。它也会因XML而失败。NTEXT头的事实。即使在<?xml … ?>将控制权返回到框架之前手动添加回xml头,错误仍然存在。SqlServerDatabaseService方法开始,我进入了框架代码,最终在xslt.Load(…;)中找到了一个方法。有一个名为Main的LoadStylesheet,它显然存储了已加载样式表的基本uri。因此,如果我们加载多个带有空的或丢失的基uri的样式表,此方法将尝试将XsltLoader.cs添加到该字典两次;这就是导致错误的原因。HybridDictionary返回的每个样式表分配了一个唯一的基uri,一切都应该正常工作。您可以通过将documentUrisInUse传递给null构造函数来完成此操作。请参阅我的答案开头的代码示例。您还可以通过downloading或克隆this Gist(IDatabaseService)检索更新的工作解决方案。
关于c# - XslCompiledTransform和自定义XmlUrlResolver:“具有相同键的条目已存在”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11864564/
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL