컨텍스트에 관계없이 SimpleXML 개체를 문자열로 강제 적용


78

이와 같은 XML이 있다고 가정 해 보겠습니다.

<channel>
  <item>
    <title>This is title 1</title>
  </item>
</channel>

아래 코드는 제목을 문자열로 출력한다는 점에서 내가 원하는 것을 수행합니다.

$xml = simplexml_load_string($xmlstring);
echo $xml->channel->item->title;

여기 내 문제가 있습니다. 아래 코드는 해당 컨텍스트에서 제목을 문자열로 취급하지 않으므로 문자열 대신 배열의 SimpleXML 개체로 끝납니다.

$foo = array( $xml->channel->item->title );

나는 이것과 같이 그것을 주위에 일하고 있었다

$foo = array( sprintf("%s",$xml->channel->item->title) );

그러나 그것은 추악한 것 같습니다.

컨텍스트에 관계없이 SimpleXML 개체를 문자열로 강제하는 가장 좋은 방법은 무엇입니까?


이를 위해 SOAP_SINGLE_ELEMENT_ARRAYS와 유사한 것을 구현하기 위해 PHP에 여러 요청을 제출했으며 다른 사람들도 똑같이 할 것을 권장합니다. SOAP_SINGLE_ELEMENT_ARRAYS는 둘 이상의 문자열을 보유 할 수있는 요소를 항상 문자열로 구문 분석하도록 강제합니다. 물론 다른 사람들이 언급했듯이 당신은 무엇을 되찾고 있는지 알아야하지만, WSDL (.NET의 "마법"기본값에 의해)이 모든 문자열을 다음과 같이 프로토 타입 한 .NET SOAP 서버에 문제가 발생했습니다. 혼합 또는 문자열 배열. 대신 현재 () '보내고 또는 타입 캐스팅의 비트가 그냥 문자열을 제공합니다
conrad10781

답변:


151

SimpleXMLObject를 문자열로 타입 캐스트합니다.

$foo = array( (string) $xml->channel->item->title );

위의 코드는 내부적으로 __toString()SimpleXMLObject를 호출 합니다. 이 메서드는 SimpleXMLObject의 매핑 체계를 방해하므로 공개적으로 사용할 수 없지만 위의 방식으로 호출 할 수 있습니다.


그것은 sprintf를 사용하는 것보다 깨끗합니다. 나는 그것을 좋아한다
Mark Biek

5
문자열 인수를받는 함수를 사용하면이 유형 캐스팅이 자동으로 수행됩니다 (예 : echo, str_replace, substr).
Ross

3
$ foo = (문자열) $ xml-> channel-> item-> title; 나는 배열이 필요하지 않기 때문에 내가 찾고 있던 것입니다. 감사.
Drazisil

1
+100 당신이 방금 내 저녁을 만들었습니다! SimpleXMLObject를 처음 사용하는 경우 추출한 vars가 화면에 제대로 '인쇄'되었지만 DB 쿼리에 실패했습니다 ... 한숨! PHP는 언제부터 엄격하게 입력 되었습니까? ;-)
megaSteve4 2012 년

1
@ megaSteve4 "PHP는 언제부터 엄격하게 입력 되었습니까?" -이것이 일어나야하는 것이 아니기 때문입니다. 대부분의 함수에는 정의 된 유형 컨텍스트가 없으므로 암시 적으로 해당 유형으로 캐스트 할 수 없습니다. 물론 입력 매개 변수를 명시 적으로 캐스팅 할 수 있기 때문에 substr등이 작동합니다. 하지만 가능한 한 빨리 캐스트를 수행하는 것이 더 안전하므로 모든 함수가 예상 한 데이터를 볼 수 있다는 것을 알고 있습니다.
IMSoP 2013

22

PHP 기능을 사용할 수 있습니다.

strval();

이 함수는 전달 된 매개 변수의 문자열 값을 리턴합니다.


3
@Mark Biek : __toString()구현 된 객체에서 작동 하며 특히이 질문의 경우 특정 유형의 객체와 매우 잘 작동합니다 SimpleXMLElement. string받아 들여진 답변 의 캐스트 와 비교할 수 있습니다 . strval()종종 함께와 편리한 콜백 함수 array_map()iterator_to_array($simpleXMLElement, false)하거나 SimpleXMLElement::xpath().
hakre 2013

9

기본 SimpleXML 메소드 SimpleXMLElement :: asXML이 있습니다 . 매개 변수에 따라 SimpleXMLElement를 xml 1.0 파일 또는 문자열에만 기록합니다.

$xml = new SimpleXMLElement($string);
$validfilename = '/temp/mylist.xml';
$xml->asXML($validfilename);    // to a file
echo $xml->asXML();             // to a string

정의되지 않은 함수 asXML에 대한 호출을 받으므로 이것이 현재 구식이라고 생각합니까?
Eoin

1
@Eoin Hmm ... 방금 내 예제를 테스트했지만 기본 PHP 7.3 설치에서 여전히 잘 작동합니다
Mixed Case

나는 그들에게 다른 문제가 있었음에 틀림 없다. 죄송합니다. 나는 지금 내 문제를 해결했습니다 :)
Eoin

3

그것을하는 또 다른 추악한 방법 :

$foo = array( $xml->channel->item->title."" );

작동하지만 예쁘지 않습니다.


3

수락 된 답변은 실제로 OP가 요청한 문자열 (문자열)이 아닌 문자열을 포함하는 배열을 반환합니다. 그 대답을 확장하려면 다음을 사용하십시오.

$foo = [ (string) $xml->channel->item->title ][0];

배열의 단일 요소 인 문자열을 반환합니다.


2

XML 데이터를 PHP 배열로 가져 오려면 다음을 수행하십시오.

// this gets all the outer levels into an associative php array
$header = array();
foreach($xml->children() as $child)
{
  $header[$child->getName()] = sprintf("%s", $child); 
}
echo "<pre>\n";
print_r($header);
echo "</pre>";

자녀를 얻으려면 다음을 수행하십시오.

$data = array();
foreach($xml->data->children() as $child)
{
  $header[$child->getName()] = sprintf("%s", $child); 
}
echo "<pre>\n";
print_r($data);
echo "</pre>";

원하는 것을 얻을 때까지 각 레벨을 통해 $ xml->을 확장 할 수 있습니다. 레벨없이 또는 원하는 다른 방법으로 모든 노드를 하나의 배열에 넣을 수도 있습니다.



0

__toString()수락 된 답변이 작성된 이후로 메소드 의 가시성을 변경했는지 확실하지 않지만 현재로서는 잘 작동합니다.

var_dump($xml->channel->item->title->__toString());

산출:

string(15) "This is title 1"

0

기본 SimpleXML 메소드 SimpleXMLElement :: asXML이 있습니다. 매개 변수에 따라 SimpleXMLElement를 xml 1.0 파일에 기록합니다. 예

$get_file= read file from path;
$itrate1=$get_file->node;
$html  = $itrate1->richcontent->html;


echo  $itrate1->richcontent->html->body->asXML();
 print_r((string) $itrate1->richcontent->html->body->asXML());

0

그냥 ''를 넣으십시오. 변수 앞에는 문자열로 변환됩니다.

$ foo = array ( ''. $ xml-> channel-> item-> title);


-1

다음은 모든 단일 자식 요소를로 형변환하는 재귀 함수입니다 String.

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION - CLEAN SIMPLE XML OBJECT
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function cleanSimpleXML($xmlObject = ''){

    // LOOP CHILDREN
    foreach ($xmlObject->children() as $child) {

        // IF CONTAINS MULTIPLE CHILDREN
        if(count($child->children()) > 1 ){

            // RECURSE
            $child = cleanSimpleXML($child);

        }else{

            // CAST
            $child = (string)$child;

        }

    }

    // RETURN CLEAN OBJECT
    return $xmlObject;

} // END FUNCTION
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.