Visual Studio做到这一点;反射器做它;现在我想和:)以编程方式检索xml文档注释
我想检索一些框架组件一些成员(即mscorlib.dll
,System.dll
等)的XML文档。我认为这将涉及:
- 找到了组装的XML文件,
- 导航到适当命名的子元素,并
- 检索所需的项目(
<summary>
,<remarks>
等)
为框架程序集保留的XML文件在哪里?解密XMLDOC命名方案的任何要点?有没有任何图书馆可以让这个过程变得更简单?
Visual Studio做到这一点;反射器做它;现在我想和:)以编程方式检索xml文档注释
我想检索一些框架组件一些成员(即mscorlib.dll
,System.dll
等)的XML文档。我认为这将涉及:
<summary>
,<remarks>
等)
为框架程序集保留的XML文件在哪里?解密XMLDOC命名方案的任何要点?有没有任何图书馆可以让这个过程变得更简单?
查找XML
对于assembly.dll它被命名为assembly.xml,而是由框架SDK安装,运行时本身并不包含.xml文件。用户不需要API文档。
位置有点复杂。它可以与当前语言环境命名的子目录(例如C:\ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 \ en)或甚至在附近的某个奇怪的目录中的dll并列。我建议以运行时查找卫星程序集的方式搜索它。
查找元素
要查找元素,你应该准备所谓的“XML的文档ID”从元数据。 AFAIR在C#语言规范中有记载,在MSDN中有一点。见Processing XML documentation。
除了不同的'xml'扩展名外,XML文件的命名与程序集文件完全相同,并且必须位于与程序集本身相同的目录中。
虽然,不能帮你解决其他两个问题。据我所知,你对自己的...
查找XML
.NET fallback locations(忽略GAC和其它无关子目录)
static FileInfo GetXmlDocFile(Assembly assembly) {
string assemblyDirPath = Path.GetDirectoryName(assembly.Location);
string fileName = Path.GetFileNameWithoutExtension(assembly.Location) +".xml";
return GetFallbackDirectories(CultureInfo.CurrentCulture)
.Select(dirName => CombinePath(assemblyDirPath, dirName, fileName))
.Select(filePath => new FileInfo(filePath))
.Where(file => file.Exists)
.First();
}
static IEnumerable<string> GetFallbackDirectories(CultureInfo culture) {
return culture
.Enumerate(c => c.Parent.Name != c.Name ? c.Parent : null)
.Select(c => c.Name);
}
static IEnumerable<T> Enumerate<T>(this T start, Func<T, T> next) {
for(T item = start; !object.Equals(item, default(T)); item = next(item))
yield return item;
}
static string CombinePath(params string[] args) {
return args.Aggregate(Path.Combine);
}
查找元件
static XElement GetDocMember(XElement docMembers, MemberInfo member) {
string memberId = GetMemberId(member);
return docMembers.Elements("member")
.Where(e => e.Attribute("name").Value == memberId)
.First();
}
static string GetMemberId(MemberInfo member) {
char memberKindPrefix = GetMemberPrefix(member);
string memberName = GetMemberFullName(member);
return memberKindPrefix + ":" + memberName;
}
static char GetMemberPrefix(MemberInfo member) {
return member.GetType().Name
.Replace("Runtime", "")[0];
}
static string GetMemberFullName(MemberInfo member) {
string memberScope = "";
if(member.DeclaringType != null)
memberScope = GetMemberFullName(member.DeclaringType);
else if(member is Type)
memberScope = ((Type)member).Namespace;
return memberScope + "." + member.Name;
}
使用示例
Type type = typeof(string);
var file = GetXmlDocFile(type.Assembly);
var docXml = XDocument.Load(file.FullName);
var docMembers = docXml.Root.Element("members");
var member = type.GetProperty("Length");
var docMember = GetDocMember(docMembers, member);
// From method.
var methodInfo = typeof(Stub).GetMethod("MethodWithGenericParameter");
var methodDoc = DocsService.GetXmlFromMember(methodInfo);
这里有一个现成的库,它可以让你做到这一点:NuDoc http://kzu.to/nudoc
阅读的mscorlib例如整个文档,将简单:
var members = Reader.Read(typeof(string).Assembly);
您可以稍后使用简单的访问者处理结果,如网站上所示。
我正在利用该库生成一个使用markdown在GitHub中进行托管的API站点,理想情况下可以在每个构建中自动生成一个API站点,甚至可以为wiki维护,以便它可以更新并循环访问代码: )。
该网页似乎已移至http://www.cazzulino.com/NuDoq/。 GitHub:https://github.com/kzu/NuDoq。 – 2016-06-13 12:45:47
请注意,这仅支持简单成员(即字段和属性),并且不支持方法参数。 – 2008-10-26 23:29:32