3

Visual Studio 做到了;反射器做到了;现在我也想要:)

我想检索某些框架程序集中的某些成员的 XML 文档(即mscorlib.dllSystem.dll等)。我认为这将涉及:

  • 查找程序集的 XML 文件,
  • 导航到适当命名的子元素,以及
  • 检索所需的项目 ( <summary>, <remarks>, 等)


框架程序集的 XML 文件保存在哪里?关于破译 XMLDOC 命名方案的任何要点?是否有任何图书馆可以使这个过程更容易?

4

6 回答 6

5

查找 xml

对于 assembly.dll,它被命名为 assembly.xml,但由 Framework SDK 安装,运行时本身不包含 .xml 文件。用户不需要 API 文档。

位置有点复杂。它可以与 dll 并排放置在以当前语言环境命名的子目录中(例如 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\en),甚至在附近一些奇怪的目录中。我建议以运行时查找附属程序集的方式搜索它。

查找元素

要查找元素,您应该从元数据中准备所谓的“xml-doc ID”。AFAIR 它记录在 C# 语言规范中,并在 MSDN 中有所记录。请参阅处理 XML 文档

于 2008-10-23T19:03:19.013 回答
4

根据伊利亚的回应

查找 xml

.NET 后备位置(忽略 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 );
}

查找元素

处理 XML 文档

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 );
于 2008-10-26T14:18:24.587 回答
2

我在 CodePlex 上维护Jolt.NET项目,并实现了执行此任务的功能。有关更多信息,请参阅Jolt库。

本质上,该库允许您以编程方式定位和查询 XML 文档注释文件,以使用元数据类型System.Reflection(即MethodInfoPropertyInfo等)中的程序集。

于 2009-07-07T04:44:47.223 回答
2

试试DocsByReflection

// From method.
var methodInfo = typeof(Stub).GetMethod("MethodWithGenericParameter");
var methodDoc = DocsService.GetXmlFromMember(methodInfo);
于 2013-04-26T15:25:57.963 回答
1

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

例如,阅读有关 mscorlib 的整个文档将非常简单:

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

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

我正在利用该库生成一个 API 站点,使用 Markdown 托管在 GitHub 中,理想情况下在每次构建时自动生成,甚至可能用于 wiki,以便它可以更新和往返代码:)。

于 2013-06-11T20:26:39.023 回答
0

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

但是,无法帮助您解决其他两个问题。AFAIK,你自己一个人……

于 2008-10-23T18:54:20.887 回答