1

私は最近、XML 名前空間と、それらを PHP で効果的に処理することに深刻な不満を抱いています。最悪の種類の犯人の例を次に示します。

<dc:type xsi:type="TypeName" xsi:identifier="NN">Others</dc:type>

preg_replace を使用して成功したのは、次を使用して (URL を壊さずに) タグの「名前空間を解除」することでした。

$xml = preg_replace(
  '/<(\/?)([^:" ].*):([^>\/ ].*)(\/?)>/msiU',
  '<$1$2_$3$4>',
  $x->readOuterXML()
);

# <dc_type xsi:type="TypeName" xsi:identifier="NN">Others</dc_type>

私ができなかったのは、正規表現の魔法がなかったため、すべての名前空間属性を同じ形式に変換することでした。最初のオカレンスは変換できましたが、繰り返し可能な条件を設定する方法がわかりません。コードが機能しなかったため (そして何をしたか思い出せません)、コードを削除しましたが、結果は次のようになりました。

<dc_type xsi_type="TypeName" xsi:identifier="NN">Others</dc_type>

一方、美しいのはこれです:

<dc_type xsi_type="TypeName" xsi_identifier="NN">Others</dc_type>

助けてくれる正規表現マスターはいますか?

4

2 に答える 2

5

私は同じことを探していましたが、XMLに対して正規表現を使用するよりもよく知っています(XML / HTMLを正規表現で解析することに関するStackOverfowの質問を検索し、回答全体を読んで理由を見つけてください。あなたはそれを見る)!

これが私が思いついたコードです:

<?php
// Some test XML
$xml = <<<XML
<root xmlns:a="bogus.a" xmlns:b="bogus.b">
    <a:first>
        <b:second>text</b:second>
    </a:first>
</root>
XML;

$sxe = new SimpleXMLElement($xml);
$dom_sxe = dom_import_simplexml($sxe);

$dom = new DOMDocument('1.0');
$dom_sxe = $dom->importNode($dom_sxe, true);
$dom_sxe = $dom->appendChild($dom_sxe);

$element = $dom->childNodes->item(0);

// See what the XML looks like before the transformation
echo "<pre>\n" . htmlspecialchars($dom->saveXML()) . "\n</pre>";
foreach ($sxe->getDocNamespaces() as $name => $uri) {
    $element->removeAttributeNS($uri, $name);
}
// See what the XML looks like after the transformation
echo "<pre>\n" . htmlspecialchars($dom->saveXML()) . "\n</pre>";
?>
于 2013-09-25T01:36:40.040 に答える
1

要素名や属性名の名前変更、属性などの名前空間関連データの変更など、完全な XML ドキュメントを書き直すにはxmlns、expat ベースの xml パーサー拡張機能を使用できます。

これは、ファイルを解析し、その場で出力を変更することで機能します。パーサーは、事前に解析されたデータを取得するコールバック関数 (いわゆるhandler ) を呼び出します。たとえば、文字列形式の要素名や配列形式の属性などです。

次に、これらの値をその場で変更し、(潜在的に変更された) データを出力できます。

このようにすると、正規表現を気にする必要がなくなります (これは、適切な XML 解析にとって重要なことです)。

私の以前の回答で、これを開始するための定型コードを見つけることができます。

于 2013-03-05T12:28:56.523 に答える