Edited at
XamarinDay 17

Xamarin.AndroidでHtmlAgilityPackを使う

More than 3 years have passed since last update.

Xamarin Advent CalendarC# 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行

修正前


HtmlWeb.cs

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;
}
}

修正後


HtmlWeb.cs

#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行

修正前


HtmlWeb.cs

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;
}
}

修正後


HtmlWeb.cs

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 CalendarC# Advent Calendar 18日目の記事はそれぞれ yuwata さんと wilfrem さんです。よろしくお願いします。