Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
PHP: DOM 関数 - Manual
[go: Go Back, main page]

PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

DOMAttr->__construct()" width="11" height="7"/> <scandir
Last updated: Sun, 23 Sep 2007

view this page in

XXXI. DOM 関数

導入

DOM 拡張モジュールを使用すると、DOM API を使用した XML ドキュメントの操作を PHP 5 で行えます。

PHP 4 では DOM XML を使用します。

注意: DOM 拡張モジュールは UTF-8 エンコーディングを使用します。ISO-8859-1 エンコーディングのテキストを扱うには utf8_encode()utf8_decode() を使用します。またその他のエンコーディングを扱うには Iconv を使用します。

インストール手順

PHP コアに含まれるため、 追加のインストール無しで使用できます。

定義済みクラス

このモジュールの API は、» DOM Level 3 の標準規格と可能な限り 一致させています。そのため、API は完全にオブジェクト指向となっています。 このモジュールを使用する際は、DOM 標準規格を意識することが大切です。

このモジュールで定義されている多くのクラスについて以下の表で説明します。 DOM 標準規格に相当するクラスについては DOMxxx という名前がつけられています。

DOMAttr

DOMNode を継承します。DOMAttr インターフェースは、DOMElement オブジェクトの 属性を表します。

コンストラクタ

メソッド

プロパティ

表 52.

名前読み込み専用説明
namestringyes属性の名前
ownerElementDOMElementyes属性を保持する要素
schemaTypeInfoboolyes未実装です。常に NULL を返します。
specifiedboolyes未実装です。常に NULL を返します。
valuestringno属性の値

DOMCharacterData

DOMNode を継承します。

メソッド

プロパティ

表 53.

名前読み込み専用説明
datastringnoノードの内容
lengthintyes内容の長さ

DOMComment

DOMCharacterData を継承します。

コンストラクタ

DOMDocument

DOMNode を継承します。

コンストラクタ

メソッド

プロパティ

表 54.

名前読み込み専用説明
actualEncodingstringyes 
configDOMConfigurationyes 
doctypeDOMDocumentTypeyes このドキュメントに関連付けられた文書型宣言
documentElementDOMElementyes ドキュメントの子ノードであるドキュメント要素に対し、 直接アクセスするために便利な属性
documentURIstringno ドキュメントの位置。未定義の場合は NULL
encodingstringno 
formatOutputboolno 
implementationDOMImplementationyes このドキュメントを処理する DOMImplementation オブジェクト
preserveWhiteSpaceboolno余分な空白を取り除かない。デフォルトは TRUE
recoverboolno 
resolveExternalsboolno 文書型宣言で外部エンティティを読み込む際に TRUE を設定する。 XML ドキュメントに文字エンティティを含める際に便利です。
standaloneboolno 
strictErrorCheckingboolnoエラー時に DOMException をスローする。デフォルトは TRUE
substituteEntitiesboolno 
validateOnParseboolnoDTD を読み込んで検証する。デフォルトは FALSE
versionstringno 
xmlEncodingstringyes XML 宣言の一部として、このドキュメントのエンコーディングを 指定する属性。指定されていない場合や不明な場合 (たとえば ドキュメントがメモリ上に存在する場合など) は NULL
xmlStandaloneboolno XML 宣言の一部として、このドキュメントがスタンドアローンか どうかを指定する。指定されていない場合は FALSE
xmlVersionstringno XML 宣言の一部として、このドキュメントのバージョン番号を指定する。 バージョン番号が定義されておらず、ドキュメントが "XML" の機能を サポートしている場合は、値は "1.0"

DOMDocumentFragment

DOMNode を継承します。

メソッド

DOMDocumentType

DOMNode を継承します。

DOMDocumentdoctype 属性を保持しており、その値は NULL あるいは DOMDocumentType オブジェクトです。

プロパティ

表 55.

名前読み込み専用説明
publicIdstringyes外部サブセットの公開 ID
systemIdstringyes 外部サブセットのシステム ID。完全 URI である場合とそうでない場合がある。
namestringyes DTD の名前。すなわち、DOCTYPE キーワードに続く値
entitiesDOMNamedNodeMapyes DTD で宣言されている一般エンティティ (外部・内部とも) を含む DOMNamedNodeMap
notationsDOMNamedNodeMapyes DTD で宣言されている記法を含む DOMNamedNodeMap
internalSubsetstringyes 内部サブセットを文字列として取得する。存在しない場合は null となる。区切りの角括弧は含まない。

DOMElement

DOMNode を継承します。

コンストラクタ

メソッド

プロパティ

表 56.

名前読み込み専用説明
schemaTypeInfoboolyes未実装。常に NULL を返す。
tagNamestringyes要素名

DOMEntity

DOMNode を継承します。

このインターフェースは、XML ドキュメント内の既知のエンティティを表します。 パース済みかどうかは関係ありません。

プロパティ

表 57.

名前読み込み専用説明
publicIdstringyes エンティティに関連付けられているパブリック ID が存在すればその値、 それ以外の場合は NULL
systemIdstringyes エンティティに関連付けられているシステム ID が存在すればその値、 それ以外の場合は NULL。これは完全な URI かもしれないし、 そうでないかもしれない。
notationNamestringyes パースされていないエンティティの場合はそのエンティティの名前、 パース済みのエンティティの場合は NULL
actualEncodingstringno 外部でパースされたエンティティの場合は、このエンティティの パース時に使用されたエンコーディングを指定する属性。内部 サブセットからのエンティティであったり未知のエンティティで あった場合は NULL
encodingstringyes 外部でパースされたエンティティの場合は、テキスト宣言の一部として このエンティティのエンコーディングを指定する属性。それ以外の 場合は NULL
versionstringyes 外部でパースされたエンティティの場合は、テキスト宣言の一部として このエンティティのバージョン番号を指定する属性。それ以外の場合は NULL

DOMEntityReference

DOMNode を継承します。

コンストラクタ

DOMException

しかるべき状況、すなわち論理的に不可能な操作を行った際などの場合に DOM 操作は例外を発生させます。

章 20. 例外(exceptions) も参照ください。

プロパティ

表 58.

名前読み込み専用説明
codeintyes発生したエラーの型を示す整数値

DOMImplementation

DOMImplementation インターフェースは、個々の ドキュメントオブジェクトモデルのインスタンス独自の操作を行うための メソッド群を提供します。

コンストラクタ

メソッド

DOMNamedNodeMap

メソッド

DOMNode

メソッド

プロパティ

表 59.

名前読み込み専用説明
nodeNamestringyes現在のノード型の正確な名前を返す
nodeValuestringnoその型に応じてノードの値を返す
nodeTypeintyesノードの型を、定義済みの定数 XML_xxx_NODE のいずれかで返す
parentNodeDOMNodeyesこのノードの親を返す
childNodesDOMNodeListyes このノードのすべての子を含む DOMNodeList。 子が存在しない場合は、空の DOMNodeList
firstChildDOMNodeyes このノードの最初の子。存在しない場合は NULL を返す
lastChildDOMNodeyes このノードの最後の子。存在しない場合は NULL を返す
previousSiblingDOMNodeyes このノードの直前のノード。存在しない場合は NULL を返す
nextSiblingDOMNodeyes このノードの直後のノード。存在しない場合は NULL を返す
attributesDOMNamedNodeMapyes このノードが DOMElement の場合は ノードの属性を含む DOMNamedNodeMap、 それ以外の場合は NULL
ownerDocumentDOMDocumentyes このノードに関連付けられている DOMDocument オブジェクト
namespaceURIstringyes このノードの名前空間 URI。指定されていない場合は NULL
prefixstringno このノードの名前空間プレフィックス。指定されていない場合は NULL
localNamestringyes このノードの名前のローカル部分を返す
baseURIstringyes このノードの完全なベース URI。もし実装が完全な URL を できなかった場合は NULL
textContentstringno このノードとその子孫ノードのテキストを返す

DOMNodeList

メソッド

プロパティ

表 60.

名前読み込み専用説明
lengthintyes リスト内のノードの数。有効な子ノードのインデックスの範囲は 0 以上 length - 1 以下

DOMNotation

DOMNode を継承します。

プロパティ

表 61.

名前読み込み専用説明
publicIdstringyes 
systemIdstringyes 

DOMProcessingInstruction

DOMNode を継承します。

コンストラクタ

プロパティ

表 62.

名前読み込み専用説明
targetstringyes 
datastringno 

DOMText

DOMCharacterData を継承します。

コンストラクタ

メソッド

プロパティ

表 63.

名前読み込み専用説明
wholeTextstringyes 

DOMXPath

コンストラクタ

メソッド

プロパティ

表 64.

名前読み込み専用説明
documentDOMDocument  

このリファレンスの多くの例では XML ファイルを使用します。その際には、 以下のような形式の book.xml を使用します。

例 504. book.xml

<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
]>
<book id="listing">
 <title>My lists</title>
 <chapter id="books">
  <title>My books</title>
  <para>
   <informaltable>
    <tgroup cols="4">
     <thead>
      <row>
       <entry>Title</entry>
       <entry>Author</entry>
       <entry>Language</entry>
       <entry>ISBN</entry>
      </row>
     </thead>
     <tbody>
      <row>
       <entry>The Grapes of Wrath</entry>
       <entry>John Steinbeck</entry>
       <entry>en</entry>
       <entry>0140186409</entry>
      </row>
      <row>
       <entry>The Pearl</entry>
       <entry>John Steinbeck</entry>
       <entry>en</entry>
       <entry>014017737X</entry>
      </row>
      <row>
       <entry>Samarcande</entry>
       <entry>Amine Maalouf</entry>
       <entry>fr</entry>
       <entry>2253051209</entry>
      </row>
      <!-- TODO: I have a lot of remaining books to add.. -->
     </tbody>
    </tgroup>
   </informaltable>
  </para>
 </chapter>
</book>

定義済み定数

以下の定数が定義されています。 この関数の拡張モジュールが PHP 組み込みでコンパイルされているか、 実行時に動的にロードされている場合のみ使用可能です。

表 65. XML 定数

定数説明
XML_ELEMENT_NODE (integer) 1ノードは DOMElement です。
XML_ATTRIBUTE_NODE (integer) 2ノードは DOMAttr です。
XML_TEXT_NODE (integer) 3ノードは DOMText です。
XML_CDATA_SECTION_NODE (integer) 4ノードは DOMCharacterData です。
XML_ENTITY_REF_NODE (integer) 5ノードは DOMEntityReference です。
XML_ENTITY_NODE (integer) 6ノードは DOMEntity です。
XML_PI_NODE (integer) 7ノードは DOMProcessingInstruction です。
XML_COMMENT_NODE (integer) 8ノードは DOMComment です。
XML_DOCUMENT_NODE (integer) 9ノードは DOMDocument です。
XML_DOCUMENT_TYPE_NODE (integer) 10ノードは DOMDocumentType です。
XML_DOCUMENT_FRAG_NODE (integer) 11ノードは DOMDocumentFragment です。
XML_NOTATION_NODE (integer) 12ノードは DOMNotation です。
XML_HTML_DOCUMENT_NODE (integer) 13 
XML_DTD_NODE (integer) 14 
XML_ELEMENT_DECL_NODE (integer) 15 
XML_ATTRIBUTE_DECL_NODE (integer) 16 
XML_ENTITY_DECL_NODE (integer) 17 
XML_NAMESPACE_DECL_NODE (integer) 18 
XML_ATTRIBUTE_CDATA (integer) 1 
XML_ATTRIBUTE_ID (integer) 2 
XML_ATTRIBUTE_IDREF (integer) 3 
XML_ATTRIBUTE_IDREFS (integer) 4 
XML_ATTRIBUTE_ENTITY (integer) 5 
XML_ATTRIBUTE_NMTOKEN (integer) 7 
XML_ATTRIBUTE_NMTOKENS (integer) 8 
XML_ATTRIBUTE_ENUMERATION (integer) 9 
XML_ATTRIBUTE_NOTATION (integer) 10 

表 66. DOMException 定数

定数説明
DOM_INDEX_SIZE_ERR (integer) 1 インデックスあるいはサイズが負です。または上限を超えています。
DOMSTRING_SIZE_ERR (integer) 2 指定したテキストは DOMString 内に収まりません。
DOM_HIERARCHY_REQUEST_ERR (integer) 3そのノードが所属できない場所に挿入されました。
DOM_WRONG_DOCUMENT_ERR (integer) 4 ノードが、もともと作成されたのと別のドキュメントで使用されました。
DOM_INVALID_CHARACTER_ERR (integer) 5 名前などで、不正な文字が指定されました。
DOM_NO_DATA_ALLOWED_ERR (integer) 6 データをサポートしていないノードでデータが指定されました。
DOM_NO_MODIFICATION_ALLOWED_ERR (integer) 7 変更が許可されていないオブジェクトを変更しようとしました。
DOM_NOT_FOUND_ERR (integer) 8 存在しないノードを参照しようとしました。
DOM_NOT_SUPPORTED_ERR (integer) 9 指定した型のオブジェクトや操作は、この実装ではサポートしていません。
DOM_INUSE_ATTRIBUTE_ERR (integer) 10 別の場所で使用中の属性を追加しようとしました。
DOM_INVALID_STATE_ERR (integer) 11 現在使用できない、あるいは使用できなくなったオブジェクトを 使用しようとしました。
DOM_SYNTAX_ERR (integer) 12不正な文字列が指定されました。
DOM_INVALID_MODIFICATION_ERR (integer) 13基底オブジェクトの型を変更しようとしました。
DOM_NAMESPACE_ERR (integer) 14 名前空間に存在しないオブジェクトを作成または変更しようとしました。
DOM_INVALID_ACCESS_ERR (integer) 15 パラメータや操作は基底オブジェクトではサポートされていません。
DOM_VALIDATION_ERR (integer) 16 insertBefore や removeChild のようなメソッドのコールによってノードの 「部分的な妥当性」が満たされなくなった際にこの例外が発生し、操作は 行われません。

目次

DOMAttr->__construct() — 新しい DOMAttr オブジェクトを作成する
DOMAttr->isId() — 属性が定義済みの ID かどうかを調べる
DOMCharacterData->appendData() — ノードの文字データの最後に文字列を追加する
DOMCharacterData->deleteData() — 指定した範囲の文字列をノードから削除する
DOMCharacterData->insertData() — 指定した 16 ビット単位のオフセットに、文字列を挿入する
DOMCharacterData->replaceData() — DOMCharacterData ノードの文字列の一部を置換する
DOMCharacterData->substringData() — ノードから指定した範囲のデータを抽出する
DOMComment->__construct() — 新しい DOMComment オブジェクトを作成する
DOMDocument->__construct() — 新しい DOMDocument オブジェクトを作成する
DOMDocument->createAttribute() — 新しい属性を作成する
DOMDocument->createAttributeNS() — 関連付けられた名前空間に新しい属性を作成する
DOMDocument->createCDATASection() — 新しい cdata ノードを作成する
DOMDocument->createComment() — 新しい comment ノードを作成する
DOMDocument->createDocumentFragment() — 新しい文書片を作成する
DOMDocument->createElement() — 新しい要素ノードを作成する
DOMDocument->createElementNS() — 関連付けられた名前空間に新しい要素を作成する
DOMDocument->createEntityReference() — 新しいエンティティ参照ノードを作成する
DOMDocument->createProcessingInstruction() — 新しい PI ノードを作成する
DOMDocument->createTextNode() — 新しいテキストノードを作成する
DOMDocument->getElementById() — id に対応する要素を検索する
DOMDocument->getElementsByTagName() — 指定したタグ名に対応するすべての要素を検索する
DOMDocument->getElementsByTagNameNS() — 指定した名前空間で、タグ名に対応するすべての要素を検索する
DOMDocument->importNode() — 現在のドキュメントにノードをインポートする
DOMDocument->load() — ファイルから XML を読み込む
DOMDocument->loadHTML() — 文字列から HTML を読み込む
DOMDocument->loadHTMLFile() — ファイルから HTML を読み込む
DOMDocument->loadXML() — 文字列から XML を読み込む
DOMDocument->normalizeDocument() — ドキュメントを正規化する
DOMDocument->registerNodeClass() — 基底ノード型を作成する際に使用する拡張クラスを登録する
DOMDocument->relaxNGValidate() — ドキュメントを relaxNG で検証する
DOMDocument->relaxNGValidateSource() — ドキュメントを relaxNG で検証する
DOMDocument->save() — 内部の XML ツリーをファイルに出力する
DOMDocument->saveHTML() — 内部のドキュメントを HTML 形式の文字列として出力する
DOMDocument->saveHTMLFile() — 内部のドキュメントを HTML 形式でファイルに出力する
DOMDocument->saveXML() — 内部の XML ツリーを文字列として出力する
DOMDocument->schemaValidate() — スキーマに基づいてドキュメントを検証する
DOMDocument->schemaValidateSource() — スキーマに基づいてドキュメントを検証する
DOMDocument->validate() — DTD に基づいてドキュメントを検証する
DOMDocument->xinclude() — DOMDocument オブジェクト内の XIncludes を置換する
DOMDocumentFragment->appendXML() — 生の XML データを追加する
DOMElement->__construct() — 新しい DOMElement オブジェクトを作成する
DOMElement->getAttribute() — 属性の値を返す
DOMElement->getAttributeNode() — 属性ノードを返す
DOMElement->getAttributeNodeNS() — 属性ノードを返す
DOMElement->getAttributeNS() — 属性の値を返す
DOMElement->getElementsByTagName() — タグ名から要素を取得する
DOMElement->getElementsByTagNameNS() — 名前空間 URI とローカル名から要素を取得する
DOMElement->hasAttribute() — 属性が存在するかどうかを調べる
DOMElement->hasAttributeNS() — 属性が存在するかどうかを調べる
DOMElement->removeAttribute() — 属性を削除する
DOMElement->removeAttributeNode() — 属性を削除する
DOMElement->removeAttributeNS() — 属性を削除する
DOMElement->setAttribute() — 新しい属性を追加する
DOMElement->setAttributeNode() — 新しい属性ノードを要素に追加する
DOMElement->setAttributeNodeNS() — 新しい属性ノードを要素に追加する
DOMElement->setAttributeNS() — 新しい属性を追加する
DOMElement->setIdAttribute() — ID 型の属性を名前で宣言する
DOMElement->setIdAttributeNode() — ID 型の属性をノードで宣言する
DOMElement->setIdAttributeNS() — ID 型の属性をローカル名および名前空間 URI で宣言する
DOMEntityReference->__construct() — 新しい DOMEntityReference オブジェクトを作成する
DOMImplementation->__construct() — 新しい DOMImplementation オブジェクトを作成する
DOMImplementation->createDocument() — 指定した型とドキュメント要素の DOMDocument オブジェクトを作成する
DOMImplementation->createDocumentType() — 空の DOMDocumentType オブジェクトを作成する
DOMImplementation->hasFeature() — DOM implementation が、指定した機能を実装しているかどうかを調べる
DOMNamedNodeMap->getNamedItem() — 名前で指定されたノードを取得する
DOMNamedNodeMap->getNamedItemNS() — ローカル名および名前空間 URI で指定したノードを取得する
DOMNamedNodeMap->item() — インデックスで指定したノードを取得する
DOMNode->appendChild() — 子要素群の最後に新しい子要素を追加する
DOMNode->cloneNode() — ノードを複製する
DOMNode->hasAttributes() — ノードが属性を保持しているかどうかを調べる
DOMNode->hasChildNodes() — ノードが子を保持しているかどうかを調べる
DOMNode->insertBefore() — 参照しているノードの前に新しい子を追加する
DOMNode->isDefaultNamespace() — 指定した namespaceURI がデフォルトの名前空間かどうかを調べる
DOMNode->isSameNode() — 2 つのノードが等しいかどうかを調べる
DOMNode->isSupported() — 指定したバージョンで機能がサポートされているかどうかを調べる
DOMNode->lookupNamespaceURI() — プレフィックスに基づいて、ノードの名前空間 URI を取得する
DOMNode->lookupPrefix() — 名前空間 URI に基づいて、ノードの名前空間プレフィックスを取得する
DOMNode->normalize() — ノードを正規化する
DOMNode->removeChild() — 子要素群から子要素を削除する
DOMNode->replaceChild() — 子を置き換える
DOMNodelist->item() — インデックスで指定したノードを取得する
DOMProcessingInstruction->__construct() — 新しい DOMProcessingInstruction オブジェクトを作成する
DOMText->__construct() — 新しい DOMText オブジェクトを作成する
DOMText->isWhitespaceInElementContent() — このテキストノードが空白を含むかどうかを示す
DOMText->splitText() — 指定したオフセットでノードを 2 つに分割する
DOMXPath->__construct() — 新しい DOMXPath オブジェクトを作成する
DOMXPath->evaluate() — 与えられた XPath 式を評価し、可能であれば結果を返す
DOMXPath->query() — 与えられた XPath 式を評価する
DOMXPath->registerNamespace() — DOMXPath オブジェクトの名前空間を登録する
dom_import_simplexml — SimpleXMLElement オブジェクトから DOMElement オブジェクトを取得する


DOMAttr->__construct()" width="11" height="7"/> <scandir
Last updated: Sun, 23 Sep 2007
 
add a note add a note User Contributed Notes
DOM 関数
PHPdeveloper
06-Sep-2007 06:46
The Yanik's dom2array() function (added on 14-Mar-2007 08:40) does not handle multiple nodes with the same name, i.e.:

<foo>
  <name>aa</name>
  <name>bb</name>
</foo>

It will overwrite former and your array will contain just the last one ("bb")
Francois Hill
02-Aug-2007 03:21
In response to lutfi at smartconsultant dot us :

(see my post on
http://fr2.php.net/manual/en/
function.dom-domdocument-getelementsbytagname.php
)

Use this class I wrote:

class XPathableNode extends DOMNode
{
    protected $Node;
    protected $DOMDocument_from_node;
    protected $DOMXpath_for_node;

    public function __construct(/* DOMNode */ $node)
    {
        $this->Node=$node;
        $this->DOMDocument_from_node=new
                                                          DomDocument();
        $domNode=$this->DOMDocument_from_node
                                  ->importNode($this->Node, true);
        $this->DOMDocument_from_node
                                 ->appendChild($domNode);
        $this->DomXpath_for_node =
                    new Domxpath($this->
                                         DOMDocument_from_node);
    }

    public function convertHTML()
    {    return $this->DOMDocument_from_node
                                                             ->saveHTML();
    }

    public /*DomNodeList*/ function applyXpath($xpath)
    {    return $this->DomXpath_for_node
                                                       ->query($xpath);
    }
}

(sorry for the display... What a terrible hinderance on the
part of php.net !)

Then :
Make a new XPathableNode out of your parent node.
You may then retrieve a DOMNodeList from it by applying a
xpath (thus being able to specify the depth  and name of
elements you want).

Has got me around some (of the many) DOM awkwardnesses a few times.

;o)
lpetrov AT axisvista.com
21-Jul-2007 09:41
Basicly there are alot of problems on dynamic namespaces registering and other maybe 'not well' documented parts of DOM.

Here is an article covering some of the problems that our company web developers found while we were developing a template engine for our new framework.

The link:
http://blog.axisvista.com/?p=35
lutfi at smartconsultant dot us
20-Jul-2007 01:06
i have some problem parsing recurred xml tree here:

<menu name='parent1' >
  <submenu name='file' >
     <submenu name='open' >Open file</submenu>
     <submenu name='close' >Close file</submenu>
  </submenu>
  <submenu name='edit' >
     <submenu name='cut' >Cut Clipboards</submenu>
     <submenu name='copy' >Copy Clipboards</submenu>
     <submenu name='paste' >Paste Clipboards</submenu>
  </submenu>
</menu>

with getElementsByTagName all submenu is on the same level.
i want it to be structured like tree list, but not change the 'submenu' tag
Sanados at failure dot at
05-Jun-2007 06:45
appended to
brian dot reynolds at risaris dot com
20-Feb-2007 10:09

when you got variable nodes at start you array fails and looses nodes  beneath.
solution that counts occurance though eats up performance:

function xmlToArray($n)
{
    $xml_array = array();
    $occurance = array();

     foreach($n->childNodes as $nc)
     {
         $occurance[$nc->nodeName]++;
     }
    
    foreach($n->childNodes as $nc){
        if( $nc->hasChildNodes() )
        {
            if($occurance[$nc->nodeName] > 1)
            {
                $xml_array[$nc->nodeName][] = xmlToArray($nc);
            }
            else
            {
                $xml_array[$nc->nodeName] = xmlToArray($nc);
            }
        }
        else
        {
            return utf8_decode($nc->nodeValue);
        }
    }
    return $xml_array;
}
Yanik <clonyara(at)ahoo(dot)com>
14-Mar-2007 04:40
I hate DOM model !
so I wrote dom2array simple function (simple for use):

function dom2array($node) {
  $res = array();
  print $node->nodeType.'<br/>';
  if($node->nodeType == XML_TEXT_NODE){
      $res = $node->nodeValue;
  }
  else{
      if($node->hasAttributes()){
          $attributes = $node->attributes;
          if(!is_null($attributes)){
              $res['@attributes'] = array();
              foreach ($attributes as $index=>$attr) {
                  $res['@attributes'][$attr->name] = $attr->value;
              }
          }
      }
      if($node->hasChildNodes()){
          $children = $node->childNodes;
          for($i=0;$i<$children->length;$i++){
              $child = $children->item($i);
              $res[$child->nodeName] = dom2array($child);
          }
      }
  }
  return $res;
}
Nevyn at N dot O dot S dot P dot A dot M dot emai dot it
11-Mar-2007 12:35
I wrote a couple of functions to:
 - create a DOMDocument from a file
 - parse the namespaces in it
 - create a XPath object with all the namespaces registered
 - load the schemalocations
 - validate the file on the main schema (the one without prefix)

It is useful for me, see if it is also for someone else!!

Giulio

function decodeNode($node)
{
    $out = $node->ownerDocument->saveXML($node);
    $re = "{^<((?:\\w*:)?\\w*)". //the tag name
    "[\\s\n\r]*((?:[\\s\n\r]*".
    "(?:\\w*:)?\\w+[\\s\n\r]*=[\\s\n\r]*". //possible attribute name
    "(?:\"[^\"]*\"|\'[^\']*\'))*)". //attribute value
    "[\\s\n\r]*>[\r\n]*".
    "((?:.*[\r\n]*)*)". //content
    "[\r\n]*</\\1>$}"; //closing tag
    preg_match($re, $out, $mat);
    return $mat;
}

function innerXml($node)
{
    $mat = decodeNode($node);
    return $mat[3];
}

function getnodeAttributes($node)
{
    $mat = decodeNode($node);
    $txt = $mat[2];
    $re = "{((?:\\w*:)?\\w+)[\\s\n\r]*=[\\s\n\r]*(\"[^\"]*\"|\'[^\']*\')}";
    preg_match_all($re, $txt, $mat);
    $att = array();
    for ($i=0; $i<count($mat[0]); $i++)
    {
        $value = $mat[2][$i];
        if ($value[0] == "\'" || $value[0] == "\"")
        {
            $len = strlen($value);
            $value = substr($value, 1, strlen($value)-2);
        }
        $att[ $mat[1][$i] ] = $value;
    }
    return $att;
}

function loadXml($file)
{
    $doc = new DOMDocument();
    $doc->load($file);
    //cerca l'attributo xmlns
    $xsi = false;
    $doc->namespaces = array();
    $doc->xpath = new DOMXPath($doc);
   
    $attr = getnodeAttributes($doc->documentElement);
    foreach ($attr as $name => $value)
    {
        if (substr($name,0,5) == "xmlns")
        {
            $uri = $value;
            $pre = $doc->documentElement->lookupPrefix($uri);
            if ($uri == "http://www.w3.org/2001/XMLSchema-instance")
                $xsi = $pre;
            $doc->namespaces[$pre] = $uri;
            if ($pre == "")
                $pre = "noname";
            $doc->xpath->registerNamespace($pre, $uri);
        }
    }
   
    if ($xsi)
    {
        $doc->schemaLocations = array();
        $lst = $doc->xpath->query("//@$xsi:schemaLocation");
        foreach($lst as $el)
        {
            $re = "{[\\s\n\r]*([^\\s\n\r]+)[\\s\n\r]*([^\\s\n\r]+)}";
            preg_match_all($re, $el->nodeValue, $mat);
            for ($i=0; $i<count($mat[0]); $i++)
            {
                $value = $mat[2][$i];
                $doc->schemaLocations[ $mat[1][$i] ] = $value;
            }
        }

        $olddir = getcwd();
        chdir(dirname($file));
        $schema = $doc->schemaLocations[$doc->namespaces[""]];
        if (substr($schema,0,7) == "file://")
        {
            $schema = substr($value,7);
        }
        if (!$doc->schemaValidate($schema))
            dbg()->err("Invalid file");
        chdir($olddir);
    }
   
    return $doc;
}
brian dot reynolds at risaris dot com
20-Feb-2007 06:09
I found the xml2array function below very useful, but there seems to be a bug in it. The $item variable was never getting set. I've expanded this out to be a bit more readable, and the corrected code is :

function xmlToArray($n)
{
    $return=array();

    foreach($n->childNodes as $nc){
        if( $nc->hasChildNodes() ){
            if( $n->firstChild->nodeName== $n->lastChild->nodeName&&$n->childNodes->length>1){
                $item = $n->firstChild;
                $return[$nc->nodeName][]=$this->xmlToArray($item);
            }
            else{
                 $return[$nc->nodeName]=$this->xmlToArray($nc);
            }
       }
       else{
           $return=$nc->nodeValue;
       }
    }
    return $return;
}
cooper at asu dot ntu-kpi dot kiev dot ua
22-Nov-2006 07:32
If you are using not object-oriented functions and it takes too much time to change them all (or you'll be replacing them later) then as a temporary decision can be used this modules:

For DOM XML:
http://alexandre.alapetite.net/doc-alex/domxml-php4-php5/

For XSLT:
http://alexandre.alapetite.net/doc-alex/xslt-php4-php5/
cormac at idreamproducts dot com
17-Oct-2006 07:48
Most email clients ignore stylesheets in HTML formatted emails.  The best way to ensure your HTML is formatted correctly by a broad spectrum of email clients, including webmail implementations as Gmail, is to use inline style attributes.  The following function uses DOM to parse an inline stylesheet, and will replace element class and id attributes with inline style attributes, and add inline style attributes for generic tag stylesheet rules.  It will remove the stylesheet and any used class and id attributes as these are defunct for most email clients.  It is a fairly lightweight function and does not support CSS inheritance, but will work for simple stylesheets e.g.:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>HTML EMAIL</title>
<style type="text/css">
body {
  margin: 10px 10px;
  font: 8pt arial;
  background: #fff;
  color: #000;
}
p {
  margin: 0 0 10px;
  line-height: 1.2em;
  text-align: justify;
}
p.centered {
  text-align: centre;
}
p#right {
  text-align: right;
}
</style>
</head>
<body>
<p>Sample text justified</p>
<p class="centered">Centered text here</p>
<p id="right">Right-aligned text</p>
</body>
</html>

Here's the function:

<?php
function parseStyleSheetfor Email($html)
{
 
$doc = new DOMDocument;
 
$doc->loadHTML($html);
 
// grab inline stylesheet as DOM object
 
$oStyle = $doc->getElementsByTagName('style')->item(0);
 
// grab rule identifiers and rules
 
preg_match_all('/^([-#._a-z0-9]+) ?\{(.*?)\}/ims', $oStyle->nodeValue, $aMatches, PREG_SET_ORDER);
  foreach (
$aMatches as $aRule) {
   
$rule_id = $aRule[1];
   
// clean up rules
   
$rule = str_replace(array("\r", "\n", '  ', '; '), array('', '', ' ', ';'), $aRule[2]);
   
$rule = preg_replace(array('/^ /', '/;$/'), '', $rule);
   
// generic rules
   
if (!strstr($rule_id, '.') && !strstr($rule_id, '#')) {
     
$items = $doc->getElementsByTagName($rule_id);
     
// set style attribute equal to rule from stylesheet
     
foreach ($items as $item) {
       
// if there is already inline style append it to end of stylesheet rule
       
$current_style = $item->getAttribute('style');
        if (!empty(
$current_style)) {
         
$item->setAttribute('style', $rule . ';' . $current_style);
        } else {
         
$item->setAttribute('style', $rule);
        }
      }
   
// classes
   
} elseif (strstr($rule_id, '.')) {
      list(
$rule_tag, $rule_class) = explode('.', $rule_id);
     
$items = $doc->getElementsByTagName($rule_tag);
      foreach (
$items as $item) {
       
$class = $item->getAttribute('class');
        if (
$class == $rule_class) {
         
// if there is already inline style append it to end of stylesheet rule
         
$current_style = $item->getAttribute('style');
          if (!empty(
$current_style)) {
           
$item->setAttribute('style', $current_style . ';' . $rule);
          } else {
           
$item->setAttribute('style', $rule);
          }
         
// remove class as it won't be used now
         
$item->removeAttribute('class');
        }
      }
   
// ids
   
} elseif (strstr($rule_id, '#')) {
      list(
$rule_tag, $id) = explode('#', $rule_id);
     
$item = $doc->getElementById($id);
     
$current_style = $item->getAttribute('style');
      if (!empty(
$current_style)) {
       
$item->setAttribute('style', $current_style . ';' . $rule);
      } else {
       
$item->setAttribute('style', $rule);
      }
     
// remove class as it won't be used now
     
$item->removeAttribute('id');
    }
  }
 
// remove inline stylesheet
 
$oStyle->parentNode->removeChild($oStyle);
  return
$doc->saveHTML();
}
?>
sean at lookin3d dot com
18-Aug-2006 02:21
$xmlDoc=<<<XML
<?xml version="1.0"?>
<methodCall>
   <methodName>examples.getStateName</methodName>
   <params>
      <param>
         <value><i4>41</i4></value>
         </param>
      </params>
   </methodCall>
XML;

$xml= new DOMDocument();
$xml->preserveWhiteSpace=false;
$xml->loadXML($xmlDoc);
print_r(xml2array($xml));

function xml2array($n)
{
    $return=array();
    foreach($n->childNodes as $nc)
    ($nc->hasChildNodes())
    ?($n->firstChild->nodeName== $n->lastChild->nodeName&&$n->childNodes->length>1)
    ?$return[$nc->nodeName][]=xml2array($item)
    :$return[$nc->nodeName]=xml2array($nc)
    :$return=$nc->nodeValue;
    return $return;
}
massimo dot scamarcia at gmail dot com
20-Feb-2006 07:56
If you're moving from PHP4 to PHP5, you can keep your scripts untouched using this:

http://alexandre.alapetite.net/doc-alex/domxml-php4-php5/index.en.html
simlee at indiana dot edu
29-Dec-2005 05:16
The project I'm currently working on uses XPaths to dynamically navigate through chunks of an XML file.  I couldn't find any PHP code on the net that would build the XPath to a node for me, so I wrote my own function.  Turns out it wasn't as hard as I thought it might be (yay recursion), though it does entail using some PHP shenanigans... 

Hopefully it'll save someone else the trouble of reinventing this wheel.

<?php
   
function getNodeXPath( $node ) {
       
// REMEMBER THAT XPATHS USE BASE-1 INSTEAD OF BASE-0!!!
       
        // Get the index for the current node by looping through the siblings.
       
$parentNode = $node->parentNode;
        if(
$parentNode != null ) {
           
$nodeIndex = 0;
            do {
               
$testNode = $parentNode->childNodes->item( $nodeIndex );
               
$nodeName = $testNode->nodeName;
               
$nodeIndex++;
               
               
// PHP trickery!  Here we create a counter based on the node
                //  name of the test node to use in the XPath.
               
if( !isset( $$nodeName ) ) $$nodeName = 1;
                else $
$nodeName++;
               
               
// Failsafe return value.
               
if( $nodeIndex > $parentNode->childNodes->length ) return( "/" );
            } while( !
$node->isSameNode( $testNode ) );
           
           
// Recursively get the XPath for the parent.
           
return( getNodeXPath( $parentNode ) . "/{$node->nodeName}[{$$nodeName}]" );
        } else {
           
// Hit the root node!  Note that the slash is added when
            //  building the XPath, so we return just an empty string.
           
return( "" );
        }
    }
?>
johanwthijs-at-hotmail-dot-com
14-Dec-2005 11:25
Being an experienced ASP developer I was wondering how to replace textual content of a node (with msxml this is simply acheived by setting the 'text' property of a node). Out of frustration I started to play around with SimpleXml but I could not get it to work in combination with xPath.

I took me a lot of time to find out so I hope this helps others:

function replaceNodeText($objXml, $objNode, $strNewContent){
    /*
    This function replaces a node's string content with strNewContent
    */
    $objNodeListNested = &$objNode->childNodes;
    foreach ( $objNodeListNested as $objNodeNested ){
         if ($objNodeNested->nodeType == XML_TEXT_NODE)$objNode->removeChild ($objNodeNested);
    }
   
    $objNode->appendChild($objXml->createTextNode($strNewContent));
}

$objXml= new DOMDocument();
$objXml->loadXML('<root><node id="1">bla</note></root>');
$objXpath = new domxpath($objXml);

$strXpath="/root/node[@id='1']";
$objNodeList = $objXpath ->query($strXpath);
foreach ($objNodeList as $objNode){
//pass the node by reference
replaceNodeText($objXml, &$objNode, $strImportedValue);
}
mark at vectrex dot org dot uk
18-Nov-2005 07:10
Note that these DOM functions expect (and presumably return) all their data in UTF-8 character encoding, regardless of what PHP's current encoding is. This means that text nodes, attribute values etc, should be in utf8.

This applies even if you're generating an XML document which is not ultimately in utf8.

Mark
toby at tobiasly dot com
23-Oct-2005 03:08
This module is not included by default either in the CentOS 4 "centosplus" repository. For those using PHP5 on CentOS 4, a simple "yum --enablerepo=centosplus install php-xml" will do the trick (this will install both the XML and DOM modules).
pes_cz
29-Sep-2005 04:32
When I tried to parse my XHTML Strict files with DOM extension, it couldn't understand xhtml entities (like &copy;). I found post about it here (14-Jul-2005 09:05) which adviced to add resolveExternals = true, but it was very slow. There was some small note about xml catalogs but without any glue. Here it is:

XML catalogs is something like cache. Download all needed dtd's to /etc/xml, edit file /etc/xml/catalog and add this line: <public publicId="-//W3C//DTD XHTML 1.0 Strict//EN" uri="file:///etc/xml/xhtml1-strict.dtd" />

Thats all. Thanks to http://www.whump.com/moreLikeThis/link/03815
amir.laherATcomplinet.com
22-Aug-2005 09:09
This particular W3C page provides invaluable documentation for the DOM classes implemented in php5 (via libxml2). It fills in plenty of php.net's gaps:

http://www.w3.org/TR/DOM-Level-2-Core/core.html

Some key examples:
* concise summary of the class heirachy (1.1.1)
* clarification that DOM level 2 doesn't allow for population of internal DTDs
* explanation of DOMNode->normalize()
* explanation of the DOMImplementation class

The interfaces are described in OMG's Interface Definition Language
aidan at php dot net
19-Jul-2005 10:04
As of PHP 5.1, libxml options may be set using constants rather than the use of proprietary DomDocument properties.

DomDocument->resolveExternals is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDATTR

DomDocument->validateOnParse is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDVALID

PHP 5.1 users are encouraged to use the new constants.

Example:

DomDocument->load($file, LIBXML_DTDLOAD|LIBXML_DTDATTR);

DomDocument->load($file, LIBXML_DTDLOAD|LIBXML_DTDVALID);
aidan at php dot net
19-Jul-2005 12:27
When dealing with validation or loading, the output errors can be quite annoying.

PHP 5.1 introduces libxml_get_errors().

http://php.net/libxml_get_errors
php at webdevelopers dot cz
15-Jul-2005 04:05
[Editor's Note: If you're using entities, then you have no choice. XML Catalogs can speed DTD resolution.]

Never use

$dom->resolveExternals=true;

when parsing XHTML document that has the DOCTYPE declaration with DTD URL specified in it.

Otherwise parsing the XHTML with DOCTYPE like this one:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

will result in PHP/DOM downloading the DTD file from W3C site when parsing your document. It will add extra delay to your script - I experienced that $dom->load()'s total time was from 1 to 16 seconds.

elixon
spammable69 at hotmail dot com
12-Apr-2005 02:18
I wrote a framework to implement the StyleSheet interfaces as specified on the W3C website.  The code is written in PHP, and is NOT a complete implementation.  Use it how ya like.  I was planning on adding the CSSStyleSheet interfaces as well.  Feel free to ask.

<?
   
class StyleSheetList {
       
public length;
       
private self;
       
        function
__construct ( ) {
           
$this->self = array();
        }
       
        function
__get($property, $&ret) {
            if(
$property == 'length')
               
$ret = count($this->self);
            return
true;
        }
       
        function
__set($property, $val) {
            if(
$property == 'length')
                return
true;
        }
       
        function
item( $index ) {
            return
$this->self[$index];
        }
    }
   
    class
MediaList extends StyleSheetList {
       
        function
appendMedium ( $newMedium ) {
           
array_push($this->self, $newMedium);
        }
       
        function
deleteMedium ( $oldMedium ) {
            foreach(
$this->self as $item) {
                if(
$item == $oldMedium ) {
                   
$item = $this->self[ $this->length-1 ];
                   
array_pop($this->self);
                    break;
                }
            }
        }
    }
   
    class
DocumentStyle {
       
public styleSheets;
       
        function
__construct ( ) {
           
$this->styleSheets = new StyleSheetList();
        }
       
        function
__set($property, $val) {
            if(
$property == 'styleSheets')
                return
true;
        }
    }
   
    class
LinkStyle {
       
public sheet;
       
        function
__construct () {
           
$this->sheet = new StyleSheet();
        }
       
        function
__set($property, $val) {
            if(
$property == 'sheet')
                return
true;
        }
    }
   
    class
StyleSheet {
       
public type;
       
public disabled;
       
public ownerNode;
       
public parentStyleSheet;
       
public href;
       
public title;
       
public media;
       
        function
__construct( $type, $disabled, $ownerNode, $parentStyleSheet, $href, $title){
           
$this->type = $type;
           
$this->disabled = $disabled;
           
$this->media = new MediaList();
           
$this->ownerNode = $ownerNode;
           
$this->parentStyleSheet = $parentStyleSheet;
           
$this->href = $href;
           
$this->title = $title;
        }
    }
?>

Only contactable via http://murpsoft.com/contact.html

DOMAttr->__construct()" width="11" height="7"/> <scandir
Last updated: Sun, 23 Sep 2007
 
 
show source | credits | sitemap | contact | advertising | mirror sites