Xamarin Advent Calendar と C# Advent Calendar の17日目の記事です。
先日、Xamarin.AndroidなプロジェクトでHtmlAgilityPackをNugetからぶち込んでもうまく動かなかった(XPathが利用できなかった)ので解決策をメモしておきます。
#XPath使いたい...
酢酸先生がPCLバージョンを使う記事を書かれているのですが、どうせならXPath(SelectNodes,SelectSingleNode)使いたいじゃんということで、本家のコードを一部修正して使います。
Xamarin.iOSでHtml Agility Packを使ってHTMLをスクレイピングする - 酢ろぐ!
それでは手順を
まず、HtmlAgilityPackのコードを Html Agility Pack - Source Code から落としてきます。 ※私がこの記事を書いている2014/12/16現在、バージョンは1.4.0です。
##1. HtmlAgilityPack.csprojを修正
Release\1_4_0\HtmlAgilityPack\HtmlAgilityPack.csprojを以下のように修正します。
28行目
修正前
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
修正後
<TargetFrameworkVersion>v(使いたいXamarin.Androidのバージョン)</TargetFrameworkVersion>
128行目
修正前
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
修正後
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
##2. HtmlWeb.csを修正
次に、VisualStudioなりXamarinStudioなりで修正したHtmlAgilityPack.csprojを開き、__コンパイルシンボルにXAMARINを追加__した後、HtmlWeb.csを以下のように修正します。
883-895行
修正前
if (!SecurityManager.IsGranted(new DnsPermission(PermissionState.Unrestricted)))
{
//do something.... not at full trust
try
{
RegistryKey reg = Registry.ClassesRoot;
reg = reg.OpenSubKey(extension, false);
if (reg != null) contentType = (string)reg.GetValue("", def);
}
catch (Exception)
{
contentType = def;
}
}
修正後
#if !XAMARIN
if (!SecurityManager.IsGranted(new DnsPermission(PermissionState.Unrestricted)))
{
//do something.... not at full trust
try
{
RegistryKey reg = Registry.ClassesRoot;
reg = reg.OpenSubKey(extension, false);
if (reg != null) contentType = (string)reg.GetValue("", def);
contentType = def;
}
catch (Exception)
{
contentType = def;
}
}
#endif
924-936行
修正前
if (SecurityManager.IsGranted(new RegistryPermission(PermissionState.Unrestricted)))
{
try
{
RegistryKey reg = Registry.ClassesRoot;
reg = reg.OpenSubKey(@"MIME\Database\Content Type\" + contentType, false);
if (reg != null) ext = (string)reg.GetValue("Extension", def);
}
catch (Exception)
{
ext = def;
}
}
修正後
if (SecurityManager.IsGranted(new RegistryPermission(PermissionState.Unrestricted)))
{
#if !XAMARIN
try
{
RegistryKey reg = Registry.ClassesRoot;
reg = reg.OpenSubKey(@"MIME\Database\Content Type\" + contentType, false);
if (reg != null) ext = (string)reg.GetValue("Extension", def);
}
catch (Exception)
{
ext = def;
}
#else
ext = def;
#endif
}
##3. ビルド
無事HtmlAgilityPack.dllが生成されていたらOKです。
#最後に
とりあえず動くようにしただけなのでHtmlWebの挙動にどう影響するのか不明ですが、SelectNodes,SelectSingleNodeあたりはちゃんと動きます(実機での動作を確認)。
どなたか
new DnsPermission(PermissionState.Unrestricted)
のよさげな修正案をお持ちの方いらっしゃいましたら教えてください...(というかこの記事がベストなのか不明)
Xamarin Advent Calendar と C# Advent Calendar 18日目の記事はそれぞれ yuwata さんと wilfrem さんです。よろしくお願いします。