파일 시스템의 실제 파일이 아닌 사용자 정의 XmlResolver를 사용하여 XslCompiledTransform에서 문서 함수 참조를 해결하려고합니다. 구식 XslTransform을 사용하면 제대로 작동하지만 컴파일 된 변환 (성능상의 이유로 사용하고 싶음)을 사용하지 않아도됩니다.XmlResolver가 XslCompiledTransform과 함께 호출되지 않았습니다.
소스 XML 문서는 다음과 같습니다
<?xml version=""1.0"" encoding=""UTF-8""?>
<StackOverflow>
</StackOverflow>
XSLT는 다음과 같습니다
<xsl:stylesheet version=""1.0""
xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""
xmlns:xs=""http://www.w3.org/2001/XMLSchema""
exclude-result-prefixes=""xs"">
<xsl:variable name=""author"" select=""document('data.xml')""/>
<xsl:template match=""/"">
<StackOverflow>
<Author>
<xsl:copy-of select=""$author/Person/*""/>
</Author>
</StackOverflow>
</xsl:template>
</xsl:stylesheet>
예상 출력은 다음과 같습니다
<?xml version="1.0" encoding="utf-16"?>
<StackOverflow>
<Author>
<FirstName>Aaron</FirstName>
<LastName>Janes</LastName>
</Author>
</StackOverflow>
내가 사용하고자하는 부분 사용자 정의 XmlResolver는 "file ('data.xml')입니다.이 파일은 디스크의 파일에서로드하고 싶지 않지만 간단하게하기 위해 상기 리졸버 내의 정적 사전, 그래서 같은 포스트의 단순성 :
namespace transform
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
public class XmlStaticResolver : XmlResolver
{
private const string PersonXml =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<Person>
<FirstName>Aaron</FirstName>
<LastName>Janes</LastName>
</Person>";
private readonly IDictionary<string, string> _input;
public XmlStaticResolver()
{
_input = new Dictionary<string, string>
{
{ "data.xml", PersonXml }
};
}
public override object GetEntity(Uri absoluteUri,
string role,
Type ofObjectToReturn)
{
var host = absoluteUri.Host;
var xml = _input[host];
var bytes = Encoding.UTF8.GetBytes(xml);
var result = new MemoryStream(bytes);
return result;
}
public override Uri ResolveUri(Uri baseUri, string relativeUri)
{
return new Uri("static://" + relativeUri);
}
}
}
리졸버 상대 URI ("인 data.xml")을 취하고 GetEntity 방법은 "데이터를 고려하도록 가짜 프로토콜 앞에 추가 .xml "을 URL의 호스트로 사용하십시오. 그런 다음 값은 정적 사전에서 조회되고 사용할 변환의 메모리 스트림으로 반환됩니다.
나는 쓸모 XmlTransform를 사용하여이 방법을 사용하면이 (가) 상기 XSLT와 방법을 변환 호출, 예를 들어, 예상대로 정확하게 작동하고 XML은 예상 된 결과 가져옵니다 내가하려고 할 때, 그러나
namespace transform
{
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
public class ObsoleteTransform
{
public string Transform(string xslt, string xml)
{
var resolver = new XmlStaticResolver();
var transform = new XslTransform { XmlResolver = resolver };
using (var transformReader = CreateXmlReader(new StringReader(xslt), resolver))
{
transform.Load(transformReader);
}
using (var writer = new StringWriter())
{
using (var xwriter = CreateXmlWriter(writer))
{
using (var inputReader = new StringReader(xml))
{
var input = new XPathDocument(inputReader);
transform.Transform(input,
new XsltArgumentList(),
xwriter);
}
}
return writer.ToString();
}
}
private static XmlReader CreateXmlReader(TextReader reader,
XmlResolver resolver)
{
var settings = new XmlReaderSettings
{
XmlResolver = resolver
};
var xreader = XmlReader.Create(reader, settings, (string)null);
return xreader;
}
private static XmlWriter CreateXmlWriter(TextWriter writer)
{
var settings = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
NewLineChars = "\r\n"
};
var xwriter = XmlWriter.Create(writer, settings);
return xwriter;
}
}
}
을
System.Xml.Xsl.XslTransformException:
An error occurred while loading document 'data.xml'.
나는이 (가) XslCompiledTransform로 변환을 시도하기 위해 사용하고있는 코드는 다음과 같습니다 : 나는 예외를 얻을 XslCompiledTransform를 사용하는
namespace transform
{
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
public class CompiledTransform
{
public string Transform(string xslt, string xml)
{
var resolver = new XmlStaticResolver();
var xsltSettings = new XsltSettings(true, true);
var transform = new XslCompiledTransform();
using (var transformReader = CreateXmlReader(new StringReader(xslt), resolver))
{
transform.Load(transformReader, xsltSettings, resolver);
}
using (var writer = new StringWriter())
{
using (var xwriter = CreateXmlWriter(writer))
{
using (var inputReader = new StringReader(xml))
{
var input = new XPathDocument(inputReader);
transform.Transform(input,
new XsltArgumentList(),
xwriter);
}
}
return writer.ToString();
}
}
private static XmlReader CreateXmlReader(TextReader reader,
XmlResolver resolver)
{
var settings = new XmlReaderSettings
{
XmlResolver = resolver
};
var xreader = XmlReader.Create(reader, settings, (string)null);
return xreader;
}
private static XmlWriter CreateXmlWriter(TextWriter writer)
{
var settings = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
NewLineChars = "\r\n"
};
var xwriter = XmlWriter.Create(writer, settings);
return xwriter;
}
}
}
컴파일 된 변환을 사용하면 resolver가 호출되지 않는 것 같습니다. 왜 아무 생각 없어?