0
Simple XMLElement Object
(    
         [IpStatus] => 1    
         [ti_pid_20642] => SimpleXmlElement Object    
               (

上記の形式の SimpleXMLElment があり、この XML は実行時に生成され、そのようなノード値は部分的にti_pid_20642dnymaicです。ti_pid_3232ti-pid_2323ti_pid_anyumber

私の質問は、これらのノードの値を取得するにはどうすればよいですか?それは PHP を使用している子ですか?

4

1 に答える 1

0

SimpleXML を使用して XML文字列で使用されるすべてのノード名を取得するには、次を使用できSimpleXMLIteratorます。

$tagnames = array_keys(iterator_to_array(
    new RecursiveIteratorIterator(
        new SimpleXMLIterator($string)
        , RecursiveIteratorIterator::SELF_FIRST
    )
));

print_r($tagnames);

これはあなたに模範的なものを与えることができます(あなたの質問では XML を与えていませんでした、Demo):

Array
(
    [0] => IpStatus
    [1] => ti_pid_20642
    [2] => dependend
    [3] => ti-pid_2323
    [4] => ti_pid_anyumber
    [5] => more
)

有効な XML を含む文字列を提供するのに問題がある場合は、既存の SimpleXML 要素を取得して、そこから XML 文字列を作成します

$string = $simpleXML->asXML();

ただし、SimpleXML オブジェクトからすべてのタグ名を取得したいが、それを文字列に変換したくない場合は、再帰的な反復子を作成することもできますSimpleXMLElement

class SimpleXMLElementIterator extends IteratorIterator implements RecursiveIterator
{
    private $element;

    public function __construct(SimpleXMLElement $element) {
        parent::__construct($element);
    }

    public function hasChildren() {
        return (bool)$this->current()->children();
    }

    public function getChildren() {
        return new self($this->current()->children());
    }
}

使い方は似ています ( Demo ):

$it      = new RecursiveIteratorIterator(
    new SimpleXMLElementIterator($xml), RecursiveIteratorIterator::SELF_FIRST
);
$tagnames = array_keys(iterator_to_array($it));

それはあなたが必要とするものに依存します。

これは、名前空間付きの要素を使用すると、単純ではなくなります。ローカル名のみを取得するか、名前空間名を取得するか、またはタグ名を含む名前空間 URI を取得するかによって異なります。

指定SimpleXMLElementIteratorされた は、名前空間全体の要素の反復をサポートするように変更できます。デフォルトでは、simplexml はデフォルトの名前空間内の要素のトラバーサルのみを提供します。

/**
 * SimpleXMLElementIterator over all child elements across namespaces 
 */
class SimpleXMLElementIterator extends IteratorIterator implements RecursiveIterator
{
    private $element;

    public function __construct(SimpleXMLElement $element) {
        parent::__construct(new ArrayIterator($element->xpath('./*')));
    }

    public function key() {
        return $this->current()->getName();
    }

    public function hasChildren() {
        return (bool)$this->current()->xpath('./*');
    }

    public function getChildren() {
        return new self($this->current());
    }
}

次に、各要素ごとに名前空間を確認する必要があります。たとえば、名前空間を使用する変更された XML ドキュメントは次のとおりです。

<root xmlns="namspace:default" xmlns:ns1="namespace.numbered.1">
    <ns1:IpStatus>1</ns1:IpStatus>
    <ti_pid_20642>
        <dependend xmlns="namspace:depending">
            <ti-pid_2323>ti-pid_2323</ti-pid_2323>
            <ti_pid_anyumber>ti_pid_anyumber</ti_pid_anyumber>
            <more xmlns:ns2="namspace.numbered.2">
                <ti_pid_20642 ns2:attribute="test">ti_pid_20642</ti_pid_20642>
                <ns2:ti_pid_20642>ti_pid_20642</ns2:ti_pid_20642>
            </more>
        </dependend>
    </ti_pid_20642>
</root>

上記の更新と組み合わせると、SimpleXMLIterator次のコード例が新しい動作を示します。

$xml = new SimpleXMLElement($string);
$it  = new RecursiveIteratorIterator(
    new SimpleXMLElementIterator($xml), RecursiveIteratorIterator::SELF_FIRST
);

$count = 0;
foreach ($it as $name => $element) {
    $nsList = $element->getNamespaces();
    list($ns, $nsUri) = each($nsList);
    printf("#%d:  %' -20s  %' -4s  %s\n", ++$count, $name, $ns, $nsUri);
}

出力 (デモ):

#1:  IpStatus              ns1   namespace.numbered.1
#2:  ti_pid_20642                namspace:default
#3:  dependend                   namspace:depending
#4:  ti-pid_2323                 namspace:depending
#5:  ti_pid_anyumber             namspace:depending
#6:  more                        namspace:depending
#7:  ti_pid_20642                namspace:depending
#8:  ti_pid_20642          ns2   namspace.numbered.2

楽しむ。

于 2012-11-04T18:14:04.390 に答える