bestsource

php SimpleXML 하위 항목이 존재하는지 확인

bestsource 2023. 8. 7. 22:46
반응형

php SimpleXML 하위 항목이 존재하는지 확인

A->b->c존재할 수도 있지만c존재하지 않을 수 있습니다.어떻게 확인하죠?

이것을 포장하는 것이 더 나을 수도 있습니다.isset()

if(isset($A->b->c)) { // c exists

그런 식으로 만약에$A또는$A->b존재하지 않는...터지지 않습니다.

SimpleXML은 항상 Object를 반환합니다.자식이 없으면 빈 개체가 반환됩니다.

if( !empty($a->b)){
  var_dump($a->b);
}

@null의 답은 정확합니다. 이를 위한 가장 간단한 방법은 다음과 같습니다.isset

if (isset($A->b->c)) { /* c exists */ }

하지만, 그 이유는 (적어도 나에게는) 명확하지 않고, 이 페이지에는 꽤 많은 잘못된 정보가 있습니다.제대로 이해하는 데 시간이 걸려서 배운 것을 공유하려고 했습니다.

일부 사람들이 지적했듯이 SimpleXMLElement의 존재하지 않는 하위 항목에 액세스하면 false 또는 null이 아닌 '빈' SimpleXMLElement가 실제로 표시됩니다.

예를 들어 b가 존재하지 않는 경우:

$b = $A->b; // $b is now an empty SimpleXMLElement
$b->getName(); // returns an empty string
isset($b); // returns true

그래서 여러분은 사용하는 것이라고 생각할지도 모릅니다.isset아이들의 존재를 테스트하는 것은 효과가 없을 것입니다. 왜냐하면 아이가 존재하지 않는다면, 우리는 여전히 빈 SimpleXMLObject를 받기 때문입니다.isset반드시 진실로 돌아올 것입니다.

하지만 실제로는 그렇지 않습니다.

isset($A->b); // returns false

이것은 저에게 꽤 놀라운 일이었습니다!그 이유는isset는 일반 함수가 아니라 PHP 언어 구조체입니다.전화할 때isset($A->b)PHP는 먼저 계산하지 않습니다.$A->b그리고 나서 그 결과를 주장으로 전달합니다.isset()대신 액세스할 수 없는 개체 속성에 대해 set이 호출될 때 동작은__isset()클래스에서 메서드를 오버로드합니다(여기서 설명). https://www.php.net/manual/en/language.oop5.overloading.php#object.isset)

그래서 수업의 저자는 결과를 통제할 수 있습니다.isset($A->b)의 결과와는 무관하게$b = $A->bSimpleXMLElement의 경우 다음과 같이 설정합니다.isset($A->b)b가 있으면 true를 반환하고 그렇지 않으면 false를 반환합니다. 즉, 하위 요소의 존재를 테스트하는 데 필요한 것입니다.

이에 대한 추가 각주 - 원래 질문은 다음의 존재를 테스트하는 것에 관한 것이었습니다.$A->b->c.사용.isset($A->b->c)중간 b가 존재하지 않더라도 이것에도 완벽하게 작동합니다.제 생각에 여기서 일어나는 일은 PHP가 처음으로 하는 것입니다.$A->b그리고 b가 존재하지 않으면 빈 SimpleXMLElement를 받고 호출합니다.__isset('c')그 빈 SimpleXMLElement에서 최종 결과를 얻을 수 있습니다.isset($A->b->c).

실험 결과 노드가 존재하는지 확인하는 유일한 신뢰할 수 있는 방법은count($xml->someNode).

테스트 사례는 다음과 같습니다. https://gist.github.com/Thinkscape/6262156

저는 그것을 사용하여 해결했습니다.children() 및 수행하기count()Count-call 앞에 @를 붙여 자식이 없는 경우 PHP 오류를 무시합니다.바보 같지만 효과가 있습니다.

$identification = $xml->identification;
if (@count($identification->children()) == 0)
  $identification = $xml->Identification;

나는 이것이 싫습니다.

만약 당신이 PHP 5.3을 가지고 있다면, 당신은 그냥 사용할 수 있습니다.$a->count()을 사용한 Scippie의 @count($a->children())잘 작동합니다.@가 필요하지 않지만 이전 PHP 구현에서는 필요할 수 있습니다.

용사를 합니다.if(isset($A->b){저는 저에게 이슈를 주었고, 그래서 저는 노력했습니다.if($A->b){그리고 그게 효과가 있었어!

메서드 xpath가 일치하는 요소의 배열을 반환하거나 false를 반환합니다.

if(false !== $A->xpath('b/c')) { ...

http://www.php.net/manual/ru/simplexmlelement.xpath.php

간단히

var_dump(count($xml->node));

xpath 사용:

function has_child(\SimpleXMLElement $parent=null, string $xpathToChild)
{
    return isset($parent) && !empty($parent->xpath('('.$xpathToChild.')[1]'));
}

$parent확인할 하위 노드의 간접 또는 직접 상위 노드입니다.$xpathToChild는 에상인아이니 xpath입에 입니다.$parent.

()[1]모든 자식 노드를 선택하고 싶지 않기 때문입니다.하나면 충분합니다.

$a->b->c가 존재하는지 확인하기

has_child($a,'b/c');

속성을 확인할 수도 있습니다.노드가 있는지 확인하려면 다음과(와)c을 가지고 있습니다.t기여하다.

has_child($a,'b/c/@t');

5.23에서 할 수 은 가PHP 5.5.23에서업확수있제다같니습다음과작방은법가세지인는을할▁using▁the▁ways제가▁in▁i다▁work▁php▁php▁5▁3같니습▁5▁confirm▁can다음과▁were방23은을 사용하는 것이었습니다.isset() count()또는empty()

각각의 결과를 보여주는 스크립트는 다음과 같습니다.

https://gist.github.com/mchelen/306f4f31f21c02cb0c24

도우미 기능을 사용하여 노드가 함수에 매개 변수로 제공된 유효한 노드인지 확인합니다.

private static function isValidNode($node) {
  return isset($node) && $node instanceof SimpleXMLElement && !empty($node);
}

사용 예:

public function getIdFromNode($node) {
  if (!self::isValidNode($node)) {
    return 0;
  }
  return (int)$node['id'];
}

내 경험을 공유하려고 생각했습니다.5.4에서 실행하면서 'isset'과 'empty'로 테스트를 해봤지만 둘 다 효과가 없었습니다.결국 is_null을 사용하게 되었습니다.

if(!is_null($xml->scheduler->outterList->innerList)) {
    //do something
}

이름 공간

XML 파일에서 이름 공간을 사용하는 경우 자식을 확인할 때 함수 호출에 이름 공간을 포함해야 합니다. 그렇지 않으면 매번 ZERO가 반환됩니다.

if ($XMLelement->children($nameSpace,TRUE)->count()){
    //do something here 
}

이전 버전은 말할 수 없지만 PHP 8.0에서처럼 다음 한 줄 기능을 사용합니다.

function elementExists(?SimpleXMLElement $element) : bool {
  return is_null($element)?false:@count($element);
}

$A = new SimpleXMLElement('<A><b><c/></b></A>');  // doc contains c
$B = new SimpleXMLElement('<B><b/></B>');         // doc does not contain c 
$C = new SimpleXMLElement('<C><x><c/></x></C>');  // doc contains c but different heirarchy

print '$A contains ->b->c : ' . (elementExists($A->b->c)?"true":"false") . PHP_EOL;
print '$B contains ->b->c : ' . (elementExists($B->b->c)?"true":"false") . PHP_EOL;
print '$C contains ->b->c : ' . (elementExists($C->b->c)?"true":"false") . PHP_EOL;

돌아온다

$A contains ->b->c : true
$B contains ->b->c : false
$C contains ->b->c : false

즉, c가 존재하는지 여부와 필요한 위치에 있는지 여부를 정확하게 판단합니다.

시도해 볼 수 있습니다.

if($A->b->c && $A->b->c != '')
if($A->b->c != null) //c exists

한다면c않으며 은 "존하지않다니습재다않"가 . 값은 다음과 같습니다.null(정확하게는 값이 없습니다.)작동하기 는 하만지, 효이가있면으려과, 다둘이것 둘 다 해야 합니다A그리고.b그럴 필요가 없습니다null그렇지 않으면 PHP가 오류를 던질 것입니다(제 생각합니다.

언급URL : https://stackoverflow.com/questions/1560827/php-simplexml-check-if-a-child-exists

반응형