2008/08/18

Hpricotでテキスト表示させると「 」が「?」になる

対処方法

require 'hpricot'
require 'hpricot/xchar'

Hpricot::XChar::PREDEFINED_U.merge!({" " => 32})←①
or
Hpricot::XChar::PREDEFINED_U.update({" " => 32})←②

doc = Hpricot('

before after

')
puts doc.inner_text

①または②を記載する。
「 」へのエンコード対応表がないので原因。
投稿を公開

JavaでのHTMLパース

protected void regist(String path) throws Exception {

try {

log.info("regist file:" + path);


String url = getURLFromPath(path);
if (StringUtils.isBlank(url)) {
log.warn("path format invalid:" + path);
return;
}

// URLコンテンツテーブル検索
Map req = new HashMap();
req.put("url", url);
List resList = urlContentSQL.select(req);

// 複数セーブポイント
// urlContentSQL.getSqlMapClient().startTransaction()

String uriFileName = path;
if (uriFileName.indexOf(':') == -1)
uriFileName = "file:" + uriFileName;

Source source = new Source(new InputStreamReader(new FileInputStream(uriFileName), "JISAutoDetect"));

String title = getTitle(source);
String txt = source.getTextExtractor().setIncludeAttributes(true).toString();
String fullTxt = txt;
String orgTxt = source.toString();

req.put("title", title);
req.put("fullTxt", fullTxt);
req.put("orgTxt", orgTxt);
// modified_datetime // デフォルトで設定される
req.put("modifiedUsrId", usrId);

String contentId = null;
// URLコンテンツテーブル新規作成
if (resList == null || resList.size() == 0) {

log.info("insert url_content");

// created_datetime デフォルトで設定される

contentId = MsgDBUtils.getUUID();
req.put("createdUsrId", usrId);
req.put("id", contentId);
urlContentSQL.insert(req);

}
// URLコンテンツテーブル更新
else {

log.info("update url_content");

contentId = (String)resList.get(0).get("id");
urlContentSQL.update(req);

}

// コンテンツタグ対応を検索
String seedUrlId = getSeedUrlIdFromPath(path);
List
resSeedUrlList = getSeedUrlIdData(seedUrlId);
if (resSeedUrlList == null || resSeedUrlList.size() == 0) {
log.error("seed_url.seed_url_id invalid:" + seedUrlId);
return;
// throw new Exception("seed_url.seed_url_id invalid:" + seedUrlId);
}

for (Map resSeedUrl : resSeedUrlList) {

Map reqContentTagMap = new HashMap();
List
resContentTagMapList = contentTagMapSQL.select(reqContentTagMap);

// コンテンツタグ対応新規作成
if (resContentTagMapList == null || resContentTagMapList.size() == 0) {

log.info("insert content_tag_map");

reqContentTagMap.put("id", MsgDBUtils.getUUID());
contentTagMapSQL.insert(reqContentTagMap);

}

}

}
catch (Exception e) {
log.error("regist error", e);
throw e;

}


}

JavaでのHTMLパース

protected void regist(String path) throws Exception {

try {

log.info("regist file:" + path);


String url = getURLFromPath(path);
if (StringUtils.isBlank(url)) {
log.warn("path format invalid:" + path);
return;
}

// URLコンテンツテーブル検索
Map req = new HashMap();
req.put("url", url);
List resList = urlContentSQL.select(req);

// 複数セーブポイント
// urlContentSQL.getSqlMapClient().startTransaction()

String uriFileName = path;
if (uriFileName.indexOf(':') == -1)
uriFileName = "file:" + uriFileName;

Source source = new Source(new InputStreamReader(new FileInputStream(uriFileName), "JISAutoDetect"));

String title = getTitle(source);
String txt = source.getTextExtractor().setIncludeAttributes(true).toString();
String fullTxt = txt;
String orgTxt = source.toString();

req.put("title", title);
req.put("fullTxt", fullTxt);
req.put("orgTxt", orgTxt);
// modified_datetime // デフォルトで設定される
req.put("modifiedUsrId", usrId);

String contentId = null;
// URLコンテンツテーブル新規作成
if (resList == null || resList.size() == 0) {

log.info("insert url_content");

// created_datetime デフォルトで設定される

contentId = MsgDBUtils.getUUID();
req.put("createdUsrId", usrId);
req.put("id", contentId);
urlContentSQL.insert(req);

}
// URLコンテンツテーブル更新
else {

log.info("update url_content");

contentId = (String)resList.get(0).get("id");
urlContentSQL.update(req);

}

// コンテンツタグ対応を検索
String seedUrlId = getSeedUrlIdFromPath(path);
List
resSeedUrlList = getSeedUrlIdData(seedUrlId);
if (resSeedUrlList == null || resSeedUrlList.size() == 0) {
log.error("seed_url.seed_url_id invalid:" + seedUrlId);
return;
// throw new Exception("seed_url.seed_url_id invalid:" + seedUrlId);
}

for (Map resSeedUrl : resSeedUrlList) {

Map reqContentTagMap = new HashMap();
List
resContentTagMapList = contentTagMapSQL.select(reqContentTagMap);

// コンテンツタグ対応新規作成
if (resContentTagMapList == null || resContentTagMapList.size() == 0) {

log.info("insert content_tag_map");

reqContentTagMap.put("id", MsgDBUtils.getUUID());
contentTagMapSQL.insert(reqContentTagMap);

}

}

}
catch (Exception e) {
log.error("regist error", e);
throw e;

}


}

2008/08/14

rubyのコード推測精度が低いことへの対処

NKFのコード推測メソッドを利用する。
str.kconv(Kconv::UTF8, NKF.guess(str))
str.toutf8だとうまくいかないことが多い。

rubyのエンコードde

2008/08/13

JRUBYでCAYENNEをつかう

registerNewObjectの部分でうまく動作しない。
ひとひねり必要そうだ。

JRUBY

配列内の項目を特定の値に入れ替える

itemList = ["aaaa", "bbbb", "cccc"]

itemList.collect! {|item|

if item == "bbbb" then
'dddd'
else
item
end
}

2008/06/04

VBSでUNICDEの全角文字数を判断する関数


' UNICODEでも全角半角の文字数を判断するメソッド
Function LenByte(ByVal s)

Dim c, i, k

c = 0

For i = 0 To Len(s) - 1

k = Mid(s, i + 1, 1)

If (Asc(k) And &HFF00) = 0 Then

c = c + 1

Else

c = c + 2

End If

Next

LenByte = c

End Function

2008/05/27

cayenne+pgpoolではまりどころ

以前、pgpoolをcayenneで利用する為について記載した。
しかし、pgpoolやjndiで再接続機能を利用する為には更に工夫が必要だ。


以下のようにTransactionクラスを継承したクラスを作成する。


import java.sql.Connection;
import java.sql.SQLException;
import java.util.Iterator;

import org.apache.cayenne.CayenneException;
import org.apache.cayenne.access.Transaction;

public class NoTransaction extends Transaction {

@Override
public void begin() {
}

@Override
public void commit() throws IllegalStateException, SQLException, CayenneException {
close();
}

@Override
public void rollback() throws IllegalStateException, SQLException, CayenneException {
close();
}

protected void close() {

if (connections == null || connections.isEmpty()) {
return;
}

Iterator it = connections.values().iterator();
while (it.hasNext()) {
try {

((Connection) it.next()).close();
}
catch (Throwable th) {
}
}

}

}


そしてSQLを実行する部分をトランザクションしないよう以下のようにする。


Transaction tx = new NoTransaction();
try {

Transaction.bindThreadTransaction(tx);

Expression expression = ExpressionFactory.matchExp(~);
SelectQuery query = new SelectQuery(Ent.class, expression);
List entList = getDataContext().performQuery(query);
if (CollectionUtils.isEmpty(entList))
return null;

return entList;

}
finally {
try {
tx.commit();
} catch (Exception e) {

}
}

2008/03/31

rubyのgem自身アップグレード

gem update --system

Tomcat5.5のログ設定

Tomcat5.5ではデフォルトのログ出力機能はlog4jからJDKのjava.util.loggingを利用するように変更された。
log4jのほうが出力フォーマットの設定等柔軟に変更できるのでlog4jにログ出力を統一しようと思ったら以下のことをやらなければならない。
①${tomcat.home}/common/libにcommons-logginとlog4jのライブラリをおく。

②${tomcat.home}/common/classesにlog4j.xmlをおく

2008/03/19

JavaのMessageFormat.formatメソッドについて

変換対象の文字列に「{」や「'」が含まれている場合は
以下のように「'{'」や「''」とする。

String s = "function aaa() '{' alert(''{0}''); '}' ";

結構はまりどころ。

Prototypeでのブラウザ判別


if (Prototype.Browser.IE6)
alert('You are using IE6');
else if (Prototype.Browser.IE)
alert('You are using IE7');
else
alert('Not IE');

2008/03/13

cayenneでPKを指定してデータを取得する時のはまりどころ

cayenneではDataObjectUtils.objectForPKによってPKを指定してデータを取得できるが
このメソッドはデフォルトでキャッシュしてしまう。なので以下のメソッドを利用しましょう。

ObjectIdQuery query = new ObjectIdQuery(new ObjectId(AAAA.class.getSimpleName(), AAAA.ID_PK_COLUMN, id), false, ObjectIdQuery.CACHE_REFRESH);
(AAAA)DataObjectUtils.objectForQuery(dataContext, query);

ここでポイントはCACHE_REFRESH を指定して常に新しい情報を取得していること。
これを指定しないとだめ
pgpoolでロードバランサ機能を利用する場合、トランザクション内のSELECTでないことが条件の一つにあげられるがCayenneではデフォルトでトランザクションを開始してしまう。

そこでトランザクションを開始させない方法は以下

try {
// トランザクションは実行しない
Transaction.bindThreadTransaction(Transaction.noTransaction());

// なんらかのクエリを発行
}
finally {
// 元にもどす
Transaction.bindThreadTransaction(null);
}

2008/01/15

postgresのはまりどころ:配列にNULLがふくまれていた場合

配列の値

Array['aaaa', 'bbbb', null]

という値をJDBCで取得する場合にgetArray()で取得された結果は
Stringの配列となります。

但し、nullの値も'null'に文字列化されセットされます。
これバグだよなー。