2008-10-23 62 views
3

Visual Studio做到这一点;反射器做它;现在我想和:)以编程方式检索xml文档注释

我想检索一些框架组件一些成员(即mscorlib.dllSystem.dll等)的XML文档。我认为这将涉及:

  • 找到了组装的XML文件,
  • 导航到适当命名的子元素,并
  • 检索所需的项目(<summary><remarks>等)


为框架程序集保留的XML文件在哪里?解密XMLDOC命名方案的任何要点?有没有任何图书馆可以让这个过程变得更简单?

回答

5

查找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

0

除了不同的'xml'扩展名外,XML文件的命名与程序集文件完全相同,并且必须位于与程序集本身相同的目录中。

虽然,不能帮你解决其他两个问题。据我所知,你对自己的...

3

基于Ilya's response

查找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); 
} 

查找元件

Processing XML Documentation

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); 
+0

请注意,这仅支持简单成员(即字段和属性),并且不支持方法参数。 – 2008-10-26 23:29:32

2

我保持在CodePlex上的Jolt.NET项目,并实施执行这个非常任务功能。请参阅Jolt图书馆了解更多信息。

在本质上,图书馆可以让你以编程方式定位和System.Reflection使用元数据类型查询XML文档注释文件组件(即MethodInfoPropertyInfo,等...)。

2

尝试DocsByReflection

// From method. 
var methodInfo = typeof(Stub).GetMethod("MethodWithGenericParameter"); 
var methodDoc = DocsService.GetXmlFromMember(methodInfo); 
1

这里有一个现成的库,它可以让你做到这一点:NuDoc http://kzu.to/nudoc

阅读的mscorlib例如整个文档,将简单:

var members = Reader.Read(typeof(string).Assembly); 

您可以稍后使用简单的访问者处理结果,如网站上所示。

我正在利用该库生成一个使用markdown在GitHub中进行托管的API站点,理想情况下可以在每个构建中自动生成一个API站点,甚至可以为wiki维护,以便它可以更新并循环访问代码: )。

+0

该网页似乎已移至http://www.cazzulino.com/NuDoq/。 GitHub:https://github.com/kzu/NuDoq。 – 2016-06-13 12:45:47