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