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->b
SimpleXMLElement의 경우 다음과 같이 설정합니다.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
'bestsource' 카테고리의 다른 글
"사일런트 모드"에서 작동할 수 있습니까? (0) | 2023.08.07 |
---|---|
이미지의 확대/축소 기능을 얻으려면 어떻게 해야 합니까? (0) | 2023.08.07 |
ConnectionString 속성이 초기화되지 않았습니다."를 수정하는 방법 (0) | 2023.08.07 |
왜 ngOnInit가 두 번 호출됩니까? (0) | 2023.08.07 |
조건부 UPDATE MariaDB(MySQL) (0) | 2023.08.07 |