ShExとSHACLの違い

概要 ShEx(Shape Expressions)Schema と SHACL(Shapes Constraint Language)の違いに関するChatGPTによる回答です。間違っている点もあるかもしれませんが、参考になりましたら幸いです。 回答 ShEx(Shape Expressions)Schema と SHACL(Shapes Constraint Language)は、どちらもRDFデータに対する検証 や制約 を定義するための言語です。両者は同じ目的を持ちながらも、構文 やアプローチ に違いがあります。以下にその違いを説明します。 1. 目的と用途 ShEx(Shape Expressions) : ShExは、RDFデータが特定の形状(Shape)に従っているかどうかを 簡潔に定義し、検証するための言語です。 主に、柔軟で簡単なスキーマ定義 を目的として設計されており、特定の形状にデータが適合するかどうかの判定がしやすいです。 スキーマ検証 が主な用途で、特定のシェイプにデータが従っているかどうかをすばやく確認できます。 SHACL(Shapes Constraint Language) : SHACLは、RDFデータに対して複雑な制約 やルール を定義するために設計されたW3C標準の言語です。 より柔軟で強力な検証機能を持ち、スキーマ定義だけでなく、制約の論理的な定義 や高次の推論 を行うことができます。 例えば、条件付き制約や、プロパティの型、データの依存関係など、より複雑なルールを記述できます。 2. 構文と表現力 ShEx : シンプルでコンパクトな構文 を持ち、RDFデータの形状を定義する際に、簡単に読み書きできるよう設計されています。 直感的で短い記述 でシェイプを定義できるため、学習コストが低く、データ検証を行う際に適しています。 例(ShExC形式): <PersonShape> { foaf:name xsd:string ; foaf:age xsd:integer ? } * これは、「`PersonShape`は、`foaf:name`として文字列型、`foaf:age`として整数型のオプションプロパティを持つ」という意味です。 SHACL : SHACLはRDFグラフ上で定義 され、検証ロジックをRDFのトリプル形式 で記述します。 SPARQLクエリを使って検証を行うことができるため、より複雑なルールや推論が可能です。 例(Turtle形式): ex:PersonShape a sh:NodeShape ; sh:targetClass foaf:Person ; sh:property [ sh:path foaf:name ; sh:datatype xsd:string ; ] ; sh:property [ sh:path foaf:age ; sh:datatype xsd:integer ; sh:maxCount 1 ; ] . * これは「`PersonShape`は、`foaf:name`として文字列型、`foaf:age`として整数型で1つまでのプロパティを持つ」という意味です。 3. 検証方法 ShEx : ...

2024年10月25日 · 1 分 · Nakamura

@samvera/rampビューアのFiles/Markersタブの使用方法

概要 IIIF Audio/Visualに対応したビューアの一つである@samvera/rampビューアのFiles/Markersタブの使用方法について調べたので備忘録です。 マニュアル Filesについては、以下に記載がありました。 https://samvera-labs.github.io/ramp/#supplementalfiles また、Markersについては、以下に記載があります。 https://samvera-labs.github.io/ramp/#markersdisplay 使用するデータ 『県政ニュース 第1巻』(県立長野図書館)を使用します。 https://www.ro-da.jp/shinshu-dcommons/library/02FT0102974177 Filesタブ renderingプロパティを読むと記載されています。renderingプロパティについては、以下のCookbookにも掲載されています。 https://iiif.io/api/cookbook/recipe/0046-rendering/ 以下のようなスクリプトにより、マニフェストファイルにrenderingプロパティを追加します。 def add_rendering(self, manifest_path): manifest = self.load_manifest(manifest_path) japan_search_id = manifest.homepage[1].id.split("/")[-1] japan_search_api_url = f"https://jpsearch.go.jp/api/item/{japan_search_id}" rendering = ResourceItem( label={ "ja": ["アイテム参照API"], }, id=japan_search_api_url, type="Dataset", format="application/json" ) manifest.rendering = rendering output_path = f"{self.input_dir}/manifest_rendering.json" with open(output_path, "w") as f: f.write(manifest.json(indent=2)) return output_path 以下のようなマニフェストファイルが作成されます。 { "@context": "http://iiif.io/api/presentation/3/context.json", "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/manifest.json", "type": "Manifest", "label": { "ja": [ "県政ニュース 第1巻" ] }, "requiredStatement": { "label": { "ja": [ "Attribution" ] }, "value": { "ja": [ "『県政ニュース 第1巻』(県立長野図書館)を改変" ] } }, "rendering": [ { "id": "https://jpsearch.go.jp/api/item/sdcommons_npl-02FT0102974177", "type": "Dataset", "label": { "ja": [ "アイテム参照API" ] }, "format": "application/json" } ], ... } ビューアでの表示例は以下です。 ...

2024年10月17日 · 3 分 · Nakamura

Omeka SのOAI-PMHリポジトリのresumptionTokenの不具合への対応

概要 Omeka SのOAI-PMHリポジトリのresumptionTokenにおいて、有効期限内にもかかわらず、以下のように、[badResumptionToken]が出力される事例に遭遇しました。 この不具合への対処方法についてメモします。 対応 以下のファイルについて、$currentTimeと$expirationTimeを比較する処理を加えたところ、有効期限内のtokenが残るようになりました。 ... private function resumeListResponse($token): void { $api = $this->serviceLocator->get('ControllerPluginManager')->get('api'); $expiredTokens = $api->search('oaipmh_repository_tokens', [ 'expired' => true, ])->getContent(); foreach ($expiredTokens as $expiredToken) { $currentTime = new \DateTime(); // 追加 $expirationTime = $expiredToken->expiration(); // 追加 if (!$expiredToken || $currentTime > $expirationTime) { // 追加 $api->delete('oaipmh_repository_tokens', $expiredToken->id()); } // 追加 } 上記のような対応をしなくてもうまくいくケースがあったので、PHPのバージョン等による違いがあるのかもしれません。 参考 参考までに、OAI-PMHリポジトリモジュールによって作成されるテーブルの中身を確認しました。 ...

2024年10月10日 · 2 分 · Nakamura

(非標準)Omeka SのOAI-PMH RepositoryモジュールでDeleteレコードを出力してみる

概要 Omeka SのOAI-PMH RepositoryモジュールでDeleteレコードを出力してみましたので、備忘録です。 背景 以下のモジュールを使用することにより、OAI-PMHのリポジトリ機能を構築することができます。 https://omeka.org/s/modules/OaiPmhRepository/ ただ、確認した限り、Deleteレコードを出力する機能はないようでした。 関連モジュール Omekaの標準機能では、削除されたリソースを保存する機能はないかと思います。 一方、以下のモジュールは削除されたリソースを保持する機能を追加します。 https://github.com/biblibre/omeka-s-module-Necropolis 本モジュールを有効化することにより、以下のように、リソースがいつ誰によって削除されたかを記録できるようになりました。 OAI-PMH Repositoryモジュールへの応用 上記のモジュールで作成される削除されたリソースの情報が格納されるテーブルを使って、Deleteレコードの出力を試みます。 以下のファイルのlistResponse関数に追記します。 private function listResponse($verb, $metadataPrefix, $cursor, $set, $from, $until): void { /** * @var \Omeka\Api\Adapter\Manager $apiAdapterManager * @var \Doctrine\ORM\EntityManager $entityManager */ $apiAdapterManager = $this->serviceLocator->get('Omeka\ApiAdapterManager'); $entityManager = $this->serviceLocator->get('Omeka\EntityManager'); $itemRepository = $entityManager->getRepository(\Omeka\Entity\Item::class); $qb = $itemRepository->createQueryBuilder('omeka_root'); $qb->select('omeka_root'); $query = new ArrayObject; $expr = $qb->expr(); // 以下を追加 if ($set === 'o:deleted') { $settings = $this->serviceLocator->get('Omeka\Settings'); $namespaceId = $settings->get('oaipmhrepository_namespace_id', 'default_namespace'); // 削除済みレコードを necropolis_resource テーブルから取得する $deletedResourceRepository = $entityManager->getRepository(\Necropolis\Entity\NecropolisResource::class); // カスタムエンティティ // oaipmhrepository_expose_mediaに応じて、mediaとitemの取得を分ける $exposeMedia = $settings->get('oaipmhrepository_expose_media', false); // デフォルトはfalse(itemのみ) if ($exposeMedia) { $qb = $deletedResourceRepository->createQueryBuilder('necropolis_resource'); } else { // Itemのみを取得する $qb = $deletedResourceRepository->createQueryBuilder('necropolis_resource') ->andWhere('necropolis_resource.resourceType = :itemType') ->setParameter('itemType', 'Omeka\Entity\Item'); } // 日付フィルタリング if ($from) { $qb->andWhere($expr->gte('necropolis_resource.deleted', ':from')); $qb->setParameter('from', $from); } if ($until) { $qb->andWhere($expr->lte('necropolis_resource.deleted', ':until')); $qb->setParameter('until', $until); } // 結果の制限とオフセット $qb->setMaxResults($this->_listLimit); $qb->setFirstResult($cursor); $paginator = new Paginator($qb, false); $rows = count($paginator); if ($rows == 0) { $this->throwError(self::OAI_ERR_NO_RECORDS_MATCH, new Message('No records match the given criteria.')); // @translate } else { if ($verb == 'ListIdentifiers') { $method = 'appendHeader'; } elseif ($verb == 'ListRecords') { $method = 'appendRecord'; } $verbElement = $this->document->createElement($verb); $this->document->documentElement->appendChild($verbElement); foreach ($paginator as $deletedEntity) { // 削除されたリソースの情報をOAI-PMHレスポンスに追加 $header = $this->document->createElement('header'); $header->setAttribute('status', 'deleted'); // 削除済みレコードとして設定 $identifier = $this->document->createElement('identifier', 'oai:' . $namespaceId . ":" . $deletedEntity->getId()); $header->appendChild($identifier); $datestamp = $this->document->createElement('datestamp', $deletedEntity->getDeleted()->format('Y-m-d\TH:i:s\Z')); $header->appendChild($datestamp); $verbElement->appendChild($header); } // Resumption Token の処理 if ($rows > ($cursor + $this->_listLimit)) { $token = $this->createResumptionToken($verb, $metadataPrefix, $cursor + $this->_listLimit, $set, $from, $until); $tokenElement = $this->document->createElement('resumptionToken', (string) $token->id()); $tokenElement->setAttribute('expirationDate', $token->expiration()->format('Y-m-d\TH:i:s\Z')); $tokenElement->setAttribute('completeListSize', (string) $rows); $tokenElement->setAttribute('cursor', (string) $cursor); $verbElement->appendChild($tokenElement); } elseif ($cursor != 0) { $tokenElement = $this->document->createElement('resumptionToken'); $verbElement->appendChild($tokenElement); } } return; } ... OAI-PMH標準には合致していない実装方法ですが、setにo:deletedを指定すると、削除レコードを返却することができます。 ...

2024年10月10日 · 2 分 · Nakamura

iiif-prezi3を使って、動画に目次を付与する

概要 iiif-prezi3を使って、動画に目次を付与する方法に関する備忘録です。 セグメントの検出 Amazon Rekognitionのビデオセグメントの検出を用います。 https://docs.aws.amazon.com/ja_jp/rekognition/latest/dg/segments.html 以下などでサンプルコードが公開されています。 https://docs.aws.amazon.com/ja_jp/rekognition/latest/dg/segment-example.html 使用するデータ 『県政ニュース 第1巻』(県立長野図書館)を使用します。 https://www.ro-da.jp/shinshu-dcommons/library/02FT0102974177 マニフェストファイルへの反映 以下の記事などを参考に、マニフェストファイルが作成済みであるとします。 以下のようなスクリプトにより、マニフェストファイルにvttファイルを追加します。 from iiif_prezi3 import Manifest, AnnotationPage, Annotation, ResourceItem, config, HomepageItem, KeyValueString #| export class IiifClient: def load_manifest(self, manifest_path): with open(manifest_path, "r") as f: manifest_json = json.load(f) manifest = Manifest(**manifest_json) return manifest def add_segment(self, manifest_path): manifest = self.load_manifest(manifest_path) path = f"{self.input_dir}/output_segment.json" with open(path, "r") as f: data = json.load(f) range_id = f"{self.prefix}/range" range_toc = manifest.make_range( id=f"{range_id}/r", label="Table of Contents" ) canvas_id = manifest.items[0].id for s in data["Segments"]: s_type = s["Type"] if s_type != "SHOT": continue index = s["Shot Index"] start = s["Start Timestamp (milliseconds)"] / 1000 end = s["End Timestamp (milliseconds)"] / 1000 range_seg = range_toc.make_range( id=f"{range_id}/r{index}", label=f"Segment {index}", ) range_seg.items.append({ "id": f"{canvas_id}#t={start},{end}", "type": "Canvas" }) output_path = f"{self.input_dir}/manifest_segment.json" with open(output_path, "w") as f: f.write(manifest.json(indent=2)) return output_path 以下のようなマニフェストファイルが作成されます。 ...

2024年10月9日 · 2 分 · Nakamura

iiif-prezi3を使って、動画に字幕を設定する

概要 iiif-prezi3を使って、動画に字幕を設定する方法に関する備忘録です。 字幕の作成 OpenAIのAPIを使用して字幕ファイルを作成しました。動画のファイルを音声ファイルに変換しています。 from openai import OpenAI from pydub import AudioSegment from dotenv import load_dotenv class VideoClient: def __init__(self): load_dotenv(verbose=True) api_key = os.getenv("OPENAI_API_KEY") self.client = OpenAI(api_key=api_key) def get_transcriptions(self, input_movie_path): audio = AudioSegment.from_file(input_movie_path) # 一時ファイルにオーディオを書き込む with tempfile.NamedTemporaryFile(suffix=".mp3") as temp_audio_file: audio.export(temp_audio_file.name, format="mp3") # MP3形式でエクスポート temp_audio_file.seek(0) # ファイルポインタを先頭に戻す # Whisper APIでトランスクリプトを取得 with open(temp_audio_file.name, "rb") as audio_file: # Whisper APIでトランスクリプトを取得 transcript = self.client.audio.transcriptions.create( model="whisper-1", file=audio_file, response_format="vtt" ) return transcript 使用するデータ 『県政ニュース 第1巻』(県立長野図書館)を使用します。 https://www.ro-da.jp/shinshu-dcommons/library/02FT0102974177 マニフェストファイルへの反映 以下の記事などを参考に、マニフェストファイルが作成済みであるとします。 以下のようなスクリプトにより、マニフェストファイルにvttファイルを追加します。 from iiif_prezi3 import Manifest, AnnotationPage, Annotation, ResourceItem, config, HomepageItem, KeyValueString #| export class IiifClient: def load_manifest(self, manifest_path): with open(manifest_path, "r") as f: manifest_json = json.load(f) manifest = Manifest(**manifest_json) return manifest def add_vtt(self, manifest_simple_path): manifest = self.load_manifest(manifest_simple_path) vtt_url = f"{self.prefix}/video.vtt" canvas = manifest.items[0] vtt_anno_page = AnnotationPage(id=f"{canvas.id}/page2") canvas.annotations = [ vtt_anno_page, ] vtt_body = ResourceItem(id=vtt_url, type="Text", format="text/vtt") vtt_anno = Annotation( id=f"{vtt_anno_page.id}/a1", motivation="supplementing", body=vtt_body, target=canvas.id, label = "WebVTT Transcript (machine-generated)" ) vtt_anno_page.add_item(vtt_anno) with open(f"{self.input_dir}/manifest_vtt.json", "w") as f: f.write(manifest.json(indent=2)) 以下のようなマニフェストファイルが作成されます。 ...

2024年10月9日 · 2 分 · Nakamura

iiif-prezi3を使って、動画にアノテーションを付与する

概要 iiif-prezi3を使って、動画にアノテーションを付与する方法に関する備忘録です。 アノテーションの付与 Amazon Rekognitionのlabel detectionを用います。 https://docs.aws.amazon.com/rekognition/latest/dg/labels.html?pg=ln&sec=ft 以下などでサンプルコードが公開されています。 https://docs.aws.amazon.com/ja_jp/rekognition/latest/dg/labels-detecting-labels-video.html 特に、GetLabelDetectionにおける集計をSEGMENTSにすることで、StartTimestampMillisとEndTimestampMillisを得ることができます。 ただし、以下の点に注意が必要です。 SEGMENTS による集計の場合、境界ボックス付きの検出されたインスタンスに関する情報は返されません。 使用するデータ 『県政ニュース 第1巻』(県立長野図書館)を使用します。 https://www.ro-da.jp/shinshu-dcommons/library/02FT0102974177 マニフェストファイルへの反映 以下の記事などを参考に、マニフェストファイルが作成済みであるとします。 以下のようなスクリプトにより、マニフェストファイルにvttファイルを追加します。 from iiif_prezi3 import Manifest, AnnotationPage, Annotation, ResourceItem, config, HomepageItem, KeyValueString #| export class IiifClient: def load_manifest(self, manifest_path): with open(manifest_path, "r") as f: manifest_json = json.load(f) manifest = Manifest(**manifest_json) return manifest def add_label_segment(self, manifest_path): manifest = self.load_manifest(manifest_path) label_path = f"{self.input_dir}/output_label_seg.json" with open(label_path, "r") as f: label_seg = json.load(f) canvas = manifest.items[0] labels = label_seg["Labels"] anno_page_id = f"{canvas.id}/page1" anno_page = AnnotationPage(id=anno_page_id) canvas.annotations.append(anno_page) for i in range(len(labels)): label = labels[i] start = label["StartTimestamp"] / 1000 end = label["EndTimestamp"] / 1000 name = label["Label"]["Name"] anno_id = f"{anno_page_id}/a{i}" anno = Annotation( id=anno_id, motivation="tagging", target=canvas.id + "#t=" + str(start) + "," + str(end), body={ "type": "TextualBody", "value": name, "format": "text/plain", } ) anno_page.add_item( anno ) output_path = f"{self.input_dir}/manifest_label_seg.json" with open(output_path, "w") as f: f.write(manifest.json(indent=2)) return output_path 以下のようなマニフェストファイルが作成されます。 ...

2024年10月9日 · 2 分 · Nakamura

Next.jsでアンダースコアから始まるURLセグメントを利用する

概要 </api/_search> のようなAPIを作成するにあたり、アンダースコアから始まるURLセグメントを作成する方法を調べましたので、備忘録です。 方法 以下に記載がありました。 https://nextjs.org/docs/app/building-your-application/routing/colocation#:~:text=js file conventions.-,Good to know,-While not a 以下、日本語訳です。 URLセグメントでアンダースコアから始まる部分を作成するには、フォルダー名に %5F(アンダースコアのURLエンコード形式)を付けてください。例: %5FfolderName。 /api/%5Fsearch/route.ts のようにファイルを作成することで、解決することができました。 まとめ 参考になりましたら幸いです。

2024年10月8日 · 1 分 · Nakamura

@elastic/search-uiのsetFilterの不具合対応

概要 @elastic/search-uiのsetFilterについて、不具合が報告されています。 https://github.com/elastic/search-ui/issues/1057 この不具合について、すでに以下のコミットで修正されています。 https://github.com/elastic/search-ui/pull/1058 ただ、2024年10月7日時点において、上記の対応がなされた最新版がリリースされていません。 そこで、独自にビルドしてリリースすることを試みましたので、その手順に関する備忘録です。 修正 まず、リポジトリをフェッチしました。 https://github.com/nakamura196/search-ui そして、以下の修正を加えました。 https://github.com/nakamura196/search-ui/commit/f7c7dc332086ca77a2c488f3de8780bbeb683324 具体的には、package.jsonと.npmrcに変更を加えました。 パッケージの公開 以下の手順により、パッケージを公開します。 1. GitHub パーソナルアクセストークンを生成 GitHub Package Registry にアクセスするためには、GitHub のパーソナルアクセストークンが必要です。以下の手順でトークンを作成します: GitHubのアカウントにログインします。 右上のプロフィール画像をクリックし、「Settings」を選択。 左側のメニューから「Developer settings」を選択。 「Personal access tokens (classic)」を選択し、「Generate new token」をクリック。 必要な権限(write:packages と read:packages など)を選択して、トークンを生成します。 2. npm にログイン 次に、GitHub Package Registry にログインするために以下のコマンドを実行します: npm login --registry=https://npm.pkg.github.com 実行すると、以下の情報が要求されます: Username: GitHub のユーザー名 Password: 先ほど生成したパーソナルアクセストークン Email: GitHub に登録しているメールアドレス 3. パッケージを再度公開 認証が完了したら、再度 npm publish を実行してパッケージを公開します。 npm publish --registry=https://npm.pkg.github.com 結果、以下のようなページが作成されました。 利用 利用するリポジトリにおいて、以下を作成します。vercelでのビルドを想定して、GITHUB_TOKENは環境変数から参照するようにしました。 @nakamura196:registry=https://npm.pkg.github.com //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} まとめ 結局上記の方法では、もともとの課題であったsetFilterの修正はうまくいかなかったのですが、パッケージの公開方法に関して、参考になる部分がありましたら幸いです。 ...

2024年10月7日 · 1 分 · Nakamura

rico-converterを試す

概要 rico-converterを試す機会がありましたので、備忘録です。 https://github.com/ArchivesNationalesFR/rico-converter 以下のように説明されています。 A tool to convert EAC-CPF and EAD 2002 XML files to RDF datasets conforming to Records in Contexts Ontology (RiC-O) (機会翻訳)EAC-CPFやEAD 2002のXMLファイルを、Records in Contexts Ontology(RiC-O)に準拠したRDFデータセットに変換するためのツール 変換する 以下に説明があります。 https://archivesnationalesfr.github.io/rico-converter/en/GettingStarted.html まず、以下から最新のzipファイルをダウンロードして、展開します。 https://github.com/ArchivesNationalesFR/rico-converter/releases/latest サンプルデータとして、input-eacとinput-eadがあるので、これらをRDFに変換します。 input-eac 本フォルダ内にあるinput-eac/FRAN_NP_051151.xmlについて、ChatGPTによる解説は以下です。 ! このXMLファイルは、EAC-CPF(Encoded Archival Context for Corporate Bodies, Persons, and Families)という形式で記述されており、フランスの文化省(Ministère de la Culture)などの組織に関する情報を体系的に整理したものです。主な要素は次の通りです: • Controlセクション: レコードに関するメタデータを含んでいます。これには、レコードID、言語の宣言、更新履歴、使用した資料の出典などが含まれます。 • Identityセクション: 法人(ここではフランスの文化省)に関する基本的な情報が記載されています。文化省の名前が変遷してきたことを示す複数の名称や、各名称が使われていた期間も詳細に記述されています。 • Descriptionセクション: 文化省の存在期間、法的地位、主要な機能、任務、さらにその歴史的な変遷に関する詳細な説明が含まれています。たとえば、1959年に設立され、法令に基づいてどのように運営されてきたか、組織の構造がどのように変化したかが説明されています。 • Relationsセクション: 他の組織や人物との関係を示しています。ここには、フランス国内の関連機関や教育機関、さらには歴代の文化相との関係が詳細に記載されており、外部のリソース(アーカイブやオンラインの情報)へのリンクも含まれています。 このXMLは、アーカイブや組織に関する情報を標準化された形式で記述し、他のデータベースやシステムと連携することを目的としています。特に、組織の歴史や関係性を追跡する際に有用です。 以下を実行します。 sh ricoconverter.sh デフォルトのまま実行すると、output-eac-20241005といったフォルダが作成され、その中にRDFファイルが出力されます。 input-ead 本フォルダ内にあるinput-ead/FRAN_IR_003500.xmlについて、ChatGPTによる解説は以下です。 ...

2024年10月5日 · 3 分 · Nakamura

Hugging Face SpacesとYOLOv5モデル(顔コレデータセットで学習済み)を使った推論アプリの構築

概要 Hugging Face Spacesと、YOLOv5モデル(顔コレデータセットで学習済み)を使った推論アプリを作成しました。 人文学オープンデータ共同利用センターが公開する顔コレデータセットは以下です。 Yingtao Tian, Chikahiko Suzuki, Tarin Clanuwat, Mikel Bober-Irizar, Alex Lamb, Asanobu Kitamoto, “KaoKore: A Pre-modern Japanese Art Facial Expression Dataset”, arXiv:2002.08595. http://codh.rois.ac.jp/face/dataset/ 推論アプリは、以下のURLからお試しいただけます。 https://huggingface.co/spaces/nakamura196/yolov5-face また以下のURLからソースコードや学習済みモデルをダウンロードすることができます。同様のアプリケーションを開発される際の参考になれば幸いです。 https://huggingface.co/spaces/nakamura196/yolov5-face/tree/main なお、アプリケーションの開発には、以下のSpaceを参考にしています。 https://huggingface.co/spaces/pytorch/YOLOv5 使い方 画像をアップロードするか、Examplesから画像を選択してご利用いただけます。以下のように認識結果を確認することができます。 『文正草子』(日本古典籍データセット(国文研所蔵)CODH配信) まとめ 検出精度が十分でない点がありますが、参考になりましたら幸いです。 現在はYOLOv5を用いたモデルですが、今後より新しいモデルも試してみたいと思います。

2024年10月5日 · 1 分 · Nakamura

ModuleNotFoundError: No module named 'huggingface_hub.utils._errors'対応

概要 Hugging FaceのSpacesにアプリをデプロイした際、以下のエラーが発生しました。このエラーに対する備忘録です。 Creating new Ultralytics Settings v0.0.6 file ✅ View Ultralytics Settings with 'yolo settings' or at '/home/user/.config/Ultralytics/settings.json' Update Settings with 'yolo settings key=value', i.e. 'yolo settings runs_dir=path/to/dir'. For help see https://docs.ultralytics.com/quickstart/#ultralytics-settings. WARNING ⚠️ DetectMultiBackend failed: No module named 'huggingface_hub.utils._errors' Traceback (most recent call last): File "/usr/local/lib/python3.10/site-packages/yolov5/helpers.py", line 38, in load_model model = DetectMultiBackend( File "/usr/local/lib/python3.10/site-packages/yolov5/models/common.py", line 338, in __init__ result = attempt_download_from_hub(w, hf_token=hf_token) File "/usr/local/lib/python3.10/site-packages/yolov5/utils/downloads.py", line 150, in attempt_download_from_hub from huggingface_hub.utils._errors import RepositoryNotFoundError ModuleNotFoundError: No module named 'huggingface_hub.utils._errors' During handling of the above exception, another exception occurred: 参考 以下の記事が参考になりました。 ...

2024年10月4日 · 1 分 · Nakamura

pythonを使ってcvatのデータを操作する

概要 pythonを使ってcvatのデータを操作する機会がありましたので、備忘録です。 セットアップ 今回はDockerを使って起動します。 git clone https://github.com/cvat-ai/cvat --depth 1 cd cvat docker compose up -d アカウントの作成 http://localhost:8080にアクセスして、アカウントを作成します。 Pythonによる操作 まず、以下のライブラリをインストールします。 pip install cvat-sdk アカウントの情報を.envに記載します。 host=http://localhost:8080 username= password= インスタンスの作成 import os from dotenv import load_dotenv import json from cvat_sdk.api_client import Configuration, ApiClient, models, apis, exceptions from cvat_sdk.api_client.models import PatchedLabeledDataRequest import requests from io import BytesIO load_dotenv(verbose=True) host = os.environ.get("host") username = os.environ.get("username") password = os.environ.get("password") configuration = Configuration( host=host, username=username, password=password ) api_client = ApiClient(configuration) タスクの作成 task_spec = { 'name': '文字の検出', "labels": [{ "name": "文字", "color": "#ff00ff", "attributes": [ { "name": "score", "mutable": True, "input_type": "text", "values": [""] } ] }], } try: # Apis can be accessed as ApiClient class members # We use different models for input and output data. For input data, # models are typically called like "*Request". Output data models have # no suffix. (task, response) = api_client.tasks_api.create(task_spec) except exceptions.ApiException as e: # We can catch the basic exception type, or a derived type print("Exception when trying to create a task: %s\n" % e) print(task) 以下のような結果が得られます。 ...

2024年10月4日 · 3 分 · Nakamura

Omeka SでのCSRF: Value is required and can’t be emptyエラーへの対応

概要 Omeka Sにおいて、多くのメディアが関連づけられたアイテムを保存しようとする際、CSRF: Value is required and can’t be emptyというエラーメッセージが表示され、保存が完了しない事象に遭遇しました。 本記事では、このエラーへの対処方法について説明します。 関連記事 以下の記事などで言及されています。既知のエラーのようで、php.iniを変更する必要があると述べられています。 https://forum.omeka.org/t/csrf-value-is-required-and-cant-be-empty/15421 https://github.com/omeka/omeka-s/issues/1472 対処方法 以下にチャットGPTによる回答を掲載します。 php.ini で max_input_vars を設定するには、以下の手順を実行してください。 php.ini ファイルを開きます。php.ini の場所は、環境によって異なるため、以下のいずれかのディレクトリにあることが多いです: /etc/php/8.x/apache2/php.ini (Apache) /etc/php/8.x/cli/php.ini (CLI) /etc/php/8.x/fpm/php.ini (PHP-FPM) max_input_vars の値を設定または変更します。設定するために、次の行を探します。または、存在しない場合は新しく追加します。 max_input_vars = 1000 1000 という値はデフォルトですが、必要に応じて大きな数に変更できます。例えば、5000に変更する場合は次のようにします。 max_input_vars = 5000 php.ini ファイルを保存します。 Webサーバーを再起動して設定を反映させます。例えば、Apache を使っている場合は、以下のコマンドを実行します。 sudo systemctl restart apache2 PHP-FPM を使用している場合は、次のように実行します。 sudo systemctl restart php8.x-fpm これで max_input_vars が設定され、Webサーバーがその設定を反映します。 まとめ 今回はmax_input_vars = 5000に設定することで、上記エラーを解消することができました。 同様のことでお困りの方の参考になりましたら幸いです。

2024年10月2日 · 1 分 · Nakamura

Drupalのカスタムモジュールで、カスタム権限を使用する

概要 Drupalのカスタムモジュールで、カスタム権限を使用する機会がありましたので、備忘録です。 背景 以下の記事で、DrupalからGitHubのActionsを実行するモジュールを紹介しました。 ただし、権限をadminister site configurationに設定しており、管理者権限のユーザしか実行することができませんでした。 この点に対応したコミットは以下です。 https://github.com/nakamura196/Drupal-module-github_webhook/commit/c3b6f57bebfeda0556c929c8ed8ed62a0eb0a5c4 方法 以下、ChatGPT 4oの回答結果を共有します。 Drupalの_permissionには、特定のアクセス権限を設定するための値を設定できます。これによって、特定の役割を持つユーザーが、そのルートにアクセスできるかどうかを制御します。 _permissionに設定できる主な値は以下のようなものです: 一般的な権限 Drupalには、いくつかの標準的な権限が用意されています。以下は一般的に使用される権限の例です: administer site configuration - サイト全体の設定を管理できる権限 access content - コンテンツへのアクセス権限 administer users - ユーザーを管理できる権限 create content - コンテンツを作成できる権限 edit any content - 任意のコンテンツを編集できる権限 delete any content - 任意のコンテンツを削除できる権限 view user profiles - ユーザープロフィールを閲覧できる権限 administer permissions - 権限を管理できる権限 access administration pages - 管理者ページへのアクセス権限 administer taxonomy - タクソノミーを管理できる権限 カスタム権限 モジュール固有の権限を作成することもできます。例えば、github_webhookモジュールに独自の権限を作成し、_permissionで使用することも可能です。 カスタム権限を作成する場合は、github_webhook.permissions.ymlに以下のように権限を定義します: access github webhook settings: title: 'Access GitHub Webhook Settings' description: 'Allows users to access and modify GitHub Webhook settings' restrict access: TRUE そして、routing.ymlでこのカスタム権限を設定します: ...

2024年9月9日 · 1 分 · Nakamura

校異源氏物語テキストDBで公開するTEI/XMLファイルに対するDTS APIのGitHubリポジトリ

概要 以下の記事で紹介したAPIのGitHubリポジトリを公開しました。 リポジトリは以下です。 https://github.com/nakamura196/dts-typescript 不完全な点があるかと思いますが、参考になりましたら幸いです。 メモ vercelのrewrite 以下のように設定することで、/へのアクセスを/api/dtsにリダイレクトさせることができました。 { "version": 2, "builds": [ { "src": "src/index.ts", "use": "@vercel/node" } ], "rewrites": [ { "source": "/api/dts(.*)", "destination": "/src/index.ts" } ], "redirects": [ { "source": "/", "destination": "/api/dts", "permanent": true } ] } collectionのID コレクションのIDとして以下を使用しています。 const COLLECTION_ID = "urn:kouigenjimonogatari"; 当初urn:プレフィックスをつけていませんでしたが、以下のMyCapytainライブラリから使用した際、urn:がない場合、/が挿入され、うまくいかないことがありました。 https://github.com/Capitains/MyCapytain まとめ 不完全な実装が多いですが、参考になりましたら幸いです。

2024年9月4日 · 1 分 · Nakamura

校異源氏物語テキストDBで公開するTEI/XMLファイルに対するDTS APIを作成する

概要 校異源氏物語テキストDBで公開するTEI/XMLファイルに対するDTS(Distributed Text Services) APIを作成したので、備忘録です。 背景 校異源氏物語テキストDBは以下です。 https://kouigenjimonogatari.github.io/ TEI/XMLファイルを公開しています。 開発したDTS 開発したDTSは以下です。 https://dts-typescript.vercel.app/api/dts Express.jsをVercelに設置しています。 DTSは以下を参考にしてください。 https://zenn.dev/nakamura196/articles/4233fe80b3e76d MyCapytainライブラリ 以下の記事で、DTSをPythonから利用するライブラリを紹介しました。 https://zenn.dev/nakamura196/articles/1f52f460025274 本ライブラリを使用して、開発したDTSを利用してみます。 Create the resolver With the following line we create the resolver : from MyCapytain.resolvers.dts.api_v1 import HttpDtsResolver resolver = HttpDtsResolver("https://dts-typescript.vercel.app/api/dts") Require metadata : let’s visit the catalog The following code is gonna find each text that is readable by Alpheios # We get the root collection root = resolver.getMetadata() # Then we retrieve dynamically all the readableDescendants : it browse automatically the API until # it does not have seen any missing texts: be careful with this one on huge repositories readable_collections = root.readableDescendants print("We found %s collections that can be parsed" % len(readable_collections)) We found 54 collections that can be parsed Printing the full tree # Note that we could also see and make a tree of the catalog. # If you are not familiar with recursivity, the next lines might be a bit complicated def show_tree(collection, char_number=1): for subcollection_id, subcollection in collection.children.items(): print(char_number*"--" + " " + subcollection.id) show_tree(subcollection, char_number+1) print(root.id) show_tree(root) default -- urn:kouigenjimonogatari ---- urn:kouigenjimonogatari.1 ---- urn:kouigenjimonogatari.2 ---- urn:kouigenjimonogatari.3 ---- urn:kouigenjimonogatari.4 ---- urn:kouigenjimonogatari.5 ---- urn:kouigenjimonogatari.6 ---- urn:kouigenjimonogatari.7 ---- urn:kouigenjimonogatari.8 ---- urn:kouigenjimonogatari.9 ---- urn:kouigenjimonogatari.10 ---- urn:kouigenjimonogatari.11 ---- urn:kouigenjimonogatari.12 ---- urn:kouigenjimonogatari.13 ---- urn:kouigenjimonogatari.14 ---- urn:kouigenjimonogatari.15 ---- urn:kouigenjimonogatari.16 ---- urn:kouigenjimonogatari.17 ---- urn:kouigenjimonogatari.18 ---- urn:kouigenjimonogatari.19 ---- urn:kouigenjimonogatari.20 ---- urn:kouigenjimonogatari.21 ---- urn:kouigenjimonogatari.22 ---- urn:kouigenjimonogatari.23 ---- urn:kouigenjimonogatari.24 ---- urn:kouigenjimonogatari.25 ---- urn:kouigenjimonogatari.26 ---- urn:kouigenjimonogatari.27 ---- urn:kouigenjimonogatari.28 ---- urn:kouigenjimonogatari.29 ---- urn:kouigenjimonogatari.30 ---- urn:kouigenjimonogatari.31 ---- urn:kouigenjimonogatari.32 ---- urn:kouigenjimonogatari.33 ---- urn:kouigenjimonogatari.34 ---- urn:kouigenjimonogatari.35 ---- urn:kouigenjimonogatari.36 ---- urn:kouigenjimonogatari.37 ---- urn:kouigenjimonogatari.38 ---- urn:kouigenjimonogatari.39 ---- urn:kouigenjimonogatari.40 ---- urn:kouigenjimonogatari.41 ---- urn:kouigenjimonogatari.42 ---- urn:kouigenjimonogatari.43 ---- urn:kouigenjimonogatari.44 ---- urn:kouigenjimonogatari.45 ---- urn:kouigenjimonogatari.46 ---- urn:kouigenjimonogatari.47 ---- urn:kouigenjimonogatari.48 ---- urn:kouigenjimonogatari.49 ---- urn:kouigenjimonogatari.50 ---- urn:kouigenjimonogatari.51 ---- urn:kouigenjimonogatari.52 ---- urn:kouigenjimonogatari.53 ---- urn:kouigenjimonogatari.54 Printing details about a specific one # Let's get a random one ! from random import randint # The index needs to be between 0 and the number of collections rand_index = randint(0, len(readable_collections)) collection = readable_collections[rand_index] # Now let's print information ? label = collection.get_label() text_id = collection.id print("Treaing `"+label+"` with id " + text_id) Treaing `総角` with id urn:kouigenjimonogatari.47 What about more detailed informations ? Like the citation scheme ? def recursive_printing_citation_scheme(citation, char_number=1): for subcitation in citation.children: print(char_number*"--" + " " + subcitation.name) recursive_printing_citation_scheme(subcitation, char_number+1) print("Maximum citation depth : ", collection.citation.depth) print("Citation System") recursive_printing_citation_scheme(collection.citation) Maximum citation depth : 1 Citation System -- line Let’s get some references ! reffs = resolver.getReffs(collection.id) print(reffs) # Nice ! DtsReferenceSet (DtsReference https://w3id.org/kouigenjimonogatari/api/items/1587-01.json> [line]>, DtsReference https://w3id.org/kouigenjimonogatari/api/items/1587-02.json> [line]>, DtsReference https://w3id.org/kouigenjimonogatari/api/items/1587-03.json> [line]>, DtsReference https://w3id.org/kouigenjimonogatari/api/items/1587-04.json> [line]>, DtsReference ... Let’s get some random passage ! # Let's get a random one ! from random import randint # The index needs to be between 0 and the number of collections rand_index = randint(0, len(reffs)-1) reff = reffs[rand_index] passage = resolver.getTextualNode(collection.id, reff) print(passage.id, passage.reference) # Let's see the XML here # For that, we need to get the mimetype right : from MyCapytain.common.constants import Mimetypes print(passage.export(Mimetypes.XML.TEI)) urn:kouigenjimonogatari.47 DtsReference https://w3id.org/kouigenjimonogatari/api/items/1640-06.json> [line]> TEI xmlns="http://www.tei-c.org/ns/1.0">dts:fragment xmlns:dts="https://w3id.org/dts/api#"> ... 考察 上記の通り、MyCapytainライブラリの基本操作に対応したDTSを構築することができました。 ...

2024年9月4日 · 3 分 · Nakamura

DTS(Distributed Text Services)を使ってみる

概要 DTS(Distributed Text Services)の使用方法を学ぶ機会があり、その備忘録です。 使用するAPI 以下で紹介されているAlpheios を使用します。 https://github.com/distributed-text-services/specifications/?tab=readme-ov-file#known-corpora-accessible-via-the-dts-api トップ https://texts.alpheios.net/api/dts collections, documents, navigationが使えることがわかります。 { "navigation": "/api/dts/navigation", "@id": "/api/dts", "@type": "EntryPoint", "collections": "/api/dts/collections", "@context": "dts/EntryPoint.jsonld", "documents": "/api/dts/document" } Collection Endpoint collections https://texts.alpheios.net/api/dts/collections 2つの下位コレクションが含まれることがわかります。 { "totalItems": 2, "member": [ { "@id": "urn:alpheios:latinLit", "@type": "Collection", "totalItems": 3, "title": "Classical Latin" }, { "@id": "urn:alpheios:greekLit", "@type": "Collection", "totalItems": 4, "title": "Ancient Greek" } ], "title": "None", "@id": "default", "@type": "Collection", "@context": { "dts": "https://w3id.org/dts/api#", "@vocab": "https://www.w3.org/ns/hydra/core#" } } Classical Latin idurn:alpheios:latinLitを指定して、コレクションをClassical Latinに限定します。 https://texts.alpheios.net/api/dts/collections?id=urn:alpheios:latinLit 3つの下位コレクションが含まれることがわかります。 { "totalItems": 3, "member": [ { "@id": "urn:cts:latinLit:phi0472", "@type": "Collection", "totalItems": 1, "title": "Catullus" }, { "@id": "urn:cts:latinLit:phi0620", "@type": "Collection", "totalItems": 1, "title": "Propertius, Sextus" }, { "@id": "urn:cts:latinLit:phi0959", "@type": "Collection", "totalItems": 1, "title": "Ovid" } ], "title": "Classical Latin", "@id": "urn:alpheios:latinLit", "@type": "Collection", "@context": { "dts": "https://w3id.org/dts/api#", "@vocab": "https://www.w3.org/ns/hydra/core#", "ns1": "http://www.w3.org/2004/02/skos/core#" }, "dts:extensions": { "ns1:prefLabel": [ { "@value": "Classical Latin", "@language": "eng" } ] } } Catullus idurn:cts:latinLit:phi0472を指定して、コレクションをCatullusに限定します。 ...

2024年9月4日 · 7 分 · Nakamura

MyCapytainライブラリを試す

概要 以下のMyCapytainライブラリを試します。 https://github.com/Capitains/MyCapytain 背景 以下の記事で、CTS(Canonical Text Service)を取り上げました。 以下のページにおいて、CITE, CTS, CapiTainSの説明がなされています。 https://brillpublishers.gitlab.io/documentation-cts/DTS_Guidelines.html The following document is about CITE, a system for the identification of texts and any other object. CTS is the name for the identification system itself. CapiTainS is the name for the software suite built around it. Before we go into details, we need to ask two questions: (機械翻訳)以下の文書は、CITE(テキストおよびその他のオブジェクトを識別するためのシステム)に関するものです。CTSは、この識別システム自体の名前です。CapiTainSは、その周りに構築されたソフトウェアスイートの名前です。詳細に入る前に、2つの質問をする必要があります。 さらに、今回使用するMyCapytainライブラリは以下のように説明されています。 MyCapytain is a python library which provides a large set of methods to interact with Text Services API such as the Canonical Text Services, the Distributed Text Services. It also provides a programming interface to exploit local textual resources developed according to the Capitains Guidelines. ...

2024年9月4日 · 6 分 · Nakamura

Canonical Text Serviceを試す

概要 Canonical Text Serviceは、以下のように説明されています。 The Canonical Text Services protocol defines interaction between a client and server providing identification of texts and retrieval of canonically cited passages of texts. (機械翻訳)Canonical Text Services (CTS) プロトコルは、テキストの識別と、正規に引用されたテキストの箇所の取得を提供するクライアントとサーバー間の相互作用を定義しています。 以下のサイトを参考にしています。 http://cts.informatik.uni-leipzig.de/Canonical_Text_Service.html 使用方法 以下を参考にしています。 https://github.com/cite-architecture/cts_spec/blob/master/md/specification.md GetCapabilities サーバーがサポートしているサービスを確認するためのリクエストです。 http://cts.informatik.uni-leipzig.de/pbc/cts/?request=GetCapabilities <GetCapabilities xmlns="http://relaxng.org/ns/structure/1.0" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns:tei="http://www.tei-c.org/ns/1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ti="http://chs.harvard.edu/xmlns/cts"> <request>GetCapabilities</request> <reply> <TextInventory tiversion="5.0.rc.1"> <corpuslicense>Public Domain</corpuslicense> <corpussource>http://paralleltext.info/data/</corpussource> <corpuslanguage>arb,ceb,ces,cym,deu,eng,fin,fra,ita,mya,rus,tgl,ukr</corpuslanguage> <corpusname>Parallel Bible Corpus</corpusname> <corpusdescription>The Bible corpus contains 1169 unique translations, which have been assigned 906 different ISO-639-3 codes. This CTS instance contains 20 bible translations from PBC that are available as Public Domain.</corpusdescription> <textgroup urn="urn:cts:pbc:bible"> <groupname>bible</groupname> <edition urn="urn:cts:pbc:bible.parallel.arb.norm:"> <title>The Bible in Arabic</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1865</publicationDate> <language>arb</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.ceb.bugna:"> <title>Cebuano Ang Biblia (Bugna Version)</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1917</publicationDate> <language>ceb</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.ces.kralicka:"> <title>Czech Bible Kralicka. Version of 1613</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1613</publicationDate> <language>ces</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.cym.morgan1804:"> <title>Beibl William Morgan. William Morgan Bible in Welsh.</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1804</publicationDate> <language>cym</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.deu.elberfelder1871:"> <title>Die Bibel in Deutsch. Elberfelder Version von 1871. The Bible in German, Elberfelder Version of 1871</title> <license>´Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1871</publicationDate> <language>deu</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.deu.elberfelder1905:"> <title>Die Bibel in Deutsch. Elberfelder 1905. The Bible in German</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1905</publicationDate> <language>deu</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.deu.luther1545:"> <title>Die Bibel in Deutsch. Luther Version von 1545. The Bible in German. Luther version of 1545.</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1545</publicationDate> <language>deu</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.deu.luther1545letztehand:"> <title>Luther 1545 (Letzte Hand). The Bible in German</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1545</publicationDate> <language>deu</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.deu.luther1912:"> <title>Die Bibel in Deutsch. Luther Version von 1912. The Bible in German. Luther version of 1912.</title> <license>public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1912</publicationDate> <language>deu</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.eng.darby:"> <title>The Bible in English. Darby Translation.</title> <license>Public Domain</license> <publicationDate>1890</publicationDate> <language>eng</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.eng.kingjames:"> <title>King James Version of the Christian Bible</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1611</publicationDate> <language>eng</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.fin.1766:"> <title>Pyhä Raamattu. Version of 1776. The Bible in Finnish</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1776</publicationDate> <language>fin</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.fra.davidmartin:"> <title>The Bible in French. David Martin Version.</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1744</publicationDate> <language>fra</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.fra.kingjames:"> <title>The Bible in French. King James Version.</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1881</publicationDate> <language>fra</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.fra.louissegond:"> <title>The Bible in French. Louis Segond Version.</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1910</publicationDate> <language>fra</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.ita.diodati:"> <title>The Bible in Italian. Giovanni Diodati Bibbia Version.</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1649</publicationDate> <language>ita</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.mya.1835:"> <title>The New Testament in Myanmar</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1835</publicationDate> <language>mya</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.rus.synodal:"> <title>Синодальный перевод. The Synodal Bible in Russian.</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1876</publicationDate> <language>rus</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.tgl.1905:"> <title>The Bible in Tagalog.</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>1905</publicationDate> <language>tgl</language> <contentType>xml</contentType> </edition> <edition urn="urn:cts:pbc:bible.parallel.ukr.2009:"> <title>Ukrainian Version. The Bible in Ukranian.</title> <license>Public Domain</license> <source>http://paralleltext.info/data/ retrieved via Canonical Text Service http://cts.informatik.uni-leipzig.de/pbc/cts/</source> <publicationDate>2009</publicationDate> <language>ukr</language> <contentType>xml</contentType> </edition> </textgroup> </TextInventory> </reply> </GetCapabilities> GetPassage 指定したURN(Uniform Resource Name)に基づいて、特定のテキストの一部を取得します。 ...

2024年9月4日 · 12 分 · Nakamura