1

Markdown、MediaWiki構文、Creole、ソースコード、およびプレーンテキストでエンコードされたファイルがいくつかあります。

これらのファイルには、漂遊XML要素が含まれている可能性があります。私が迷うと言うとき、それらは次のようなXMLではないファイルにあります。

  • QUnitには<reference path=""/>単体テストがあります
  • JavadocにはXML要素が含まれています

この要素を最も信頼できる方法で抽出するにはどうすればよいですか?これはXMLドキュメントではありませんが、XML要素自体は整形式です。

私は要素の内容を抽出するためにsedで遊んでいます:

gsed  -n '/<myelement>/,/<\/myelement>/p' < test.txt > output.txt

これにより、ファイルからすべての非XMLが削除され、カスタム要素が残ります。これでは、それぞれを個別に処理することはできません。次に、結果のファイルに対してxmlstarletを実行できますが、これでは、要素がソースドキュメントのどこに表示されているかがわかりません。

これを行うための最良の方法は何ですか?sedを一度に1つずつ一致するように変更するにはどうすればよいですか(自分で置き換えることができます)。

ファイル全体をルート要素に読み込んでから、XMLツールを使用して半構造化XMLファイルであるかのようにファイルを処理し、XML解析で置換を処理する方がよいでしょうか。

4

2 に答える 2

2

(正規表現ベースの)ソリューションが正しいxmlテキストを抽出する場合、ネストされていないことgsedを前提として、ソリューションを拡張して開始/終了位置を含めることができます。<myelement>

$ perl -0777 -ne 'print "start: $-[0], end: $+[0], xml: {{{$&}}}\n" while /<myelement>.*?<\/myelement>/gs' < input > output

入力

some arbitrary text
A well-formed xml:

<myelement>
... xml here
</myelement>

some arbitrary text follows more elements: <myelement>... xml</myelement> the end

出力

start: 40, end: 77, xml: {{{<myelement>
... xml here
</myelement>}}}
start: 122, end: 152, xml: {{{<myelement>... xml</myelement>}}}

これは、各ルート要素がネストされておらず、Pythonの一致パターンに基づくコメントやcdataにないことを前提として、プレーンテキストの一部のxml要素に一致する正規表現を構築するPythonソリューション です。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import sys
from xml.etree import ElementTree as etree

# build regex that matches xml element
# xml_element = start_tag <anything> end_tag
#             | self_close_tag
xml_element = '(?xs) {start_tag} (?(self_close) |.*? {end_tag})'

# start_tag = '<' name  *attr '>'
# self_close_tag = '<' name *attr '/>'
ws = r'[ \t\r\n]*'  # whitespace
start_tag = '< (?P<name>{name}) {ws} (?:{attr} {ws})* (?P<self_close> / )? >'
end_tag = '</ (?P=name) >'
name = '[a-zA-Z]+'  # note: expand if necessary but the stricter the better
attr = '{name} {ws} = {ws} "[^"]*"'  # match attribute
                                     #  - fragile against missing '"'
                                     #  - no “'” support
assert '{{' not in xml_element
while '{' in xml_element: # unwrap definitions
    xml_element = xml_element.format(**vars())

# extract xml from stdin
all_text = sys.stdin.read()
for m in re.finditer(xml_element, all_text):
    print("start: {span[0]}, end: {span[1]}, xml: {begin}{xml}{end}".format(
            span=m.span(), xml=m.group(), begin="{{{", end="}}}"))
    # assert well-formness of the matched xml text by parsing it
    etree.XML(m.group())

多種多様なxml要素を照合することと誤検知を回避することの間にはトレードオフがあります。

より堅牢なソリューションでは、入力の形式を考慮に入れる必要があります。つまり、QUnit、Javadocレクサー/パーサーは、後でxmlパーサーにフィードできるxmlフラグメントを抽出するのに役立ちます。

注意:

正規表現を使用してHTML/XMLを解析できない理由:素人の用語での正式な説明

正規表現を使用してXMLとHTMLを解析するのが難しい理由の例をいくつか挙げてください。

于 2012-12-16T08:21:28.267 に答える
1

要素を手動で抽出する必要はありませんでした。処理中にデータをルートノードにラップすることで、包括的なXMLエコシステムを利用できます。

たとえば、JavaソースファイルまたはJavascriptファイルは、ルート要素内にある場合、技術的にはXMLです。

その後、XPathやSAXなどの目的のために設計されたツールを使用できます。xmlstarletを使用しました。

于 2013-01-01T20:21:29.230 に答える