복붙노트

참조 - SimpleXML에서 네임 스페이스 (콜론이있는 태그와 속성)를 처리하려면 어떻게해야합니까?

PHP

참조 - SimpleXML에서 네임 스페이스 (콜론이있는 태그와 속성)를 처리하려면 어떻게해야합니까?

이 질문은 다른 형식을 취할 수있는 특히 일반적인 질문에 대한 답변으로 참조하기위한 것입니다.

귀하의 질문이이 사본으로 끝난 경우,이 예와 동일하지 않을 수 있지만이 페이지는 귀하가 알아야 할 것을 알려줍니다.

다음은 예제입니다.

$xml = '
    <?xml version="1.0" encoding="utf-8"?>
    <document xmlns="http://example.com" xmlns:ns2="https://namespaces.example.org/two" xmlns:seq="urn:example:sequences">
        <list type="short">
            <ns2:item seq:position="1">A thing</ns2:item>
            <ns2:item seq:position="2">Another thing</ns2:item>
        </list>
    </document>
';
$sx = simplexml_load_string($xml);

이 코드는 작동하지 않습니다. 왜 안돼?

foreach ( $sx->list->ns2:item as $item ) {
    echo 'Position: ' . $item['seq:position'] . "\n";
    echo 'Item: ' . (string)$item . "\n";
}

첫 번째 문제는 -> ns2 : item이 유효하지 않은 구문입니다. 그러나 이것을 다음과 같이 변경해도 작동하지 않습니다.

foreach ( $sx->list->{'ns2:item'} as $item ) { ... }

왜 안되며, 대신 무엇을 사용해야합니까?

해결법

  1. ==============================

    1.태그 또는 속성 이름의 콜론 (:)은 요소 또는 속성이 XML 이름 공간에 있음을 의미합니다. 네임 스페이스는 하나의 문서에서 다양한 XML 형식 / 표준을 결합하고 어떤 형식에서 어떤 이름을 가져 왔는지 추적하는 방법입니다. 콜론과 그 앞에있는 부분은 실제로 태그 / 속성 이름의 일부가 아니며 단지 네임 스페이스가 있음을 나타냅니다.

    태그 또는 속성 이름의 콜론 (:)은 요소 또는 속성이 XML 이름 공간에 있음을 의미합니다. 네임 스페이스는 하나의 문서에서 다양한 XML 형식 / 표준을 결합하고 어떤 형식에서 어떤 이름을 가져 왔는지 추적하는 방법입니다. 콜론과 그 앞에있는 부분은 실제로 태그 / 속성 이름의 일부가 아니며 단지 네임 스페이스가 있음을 나타냅니다.

    XML 네임 스페이스에는 URI (URL 또는 URN)로 식별되는 네임 스페이스 식별자가 있습니다. URI는 아무 것도 가리 키지 않으며, 누군가가 네임 스페이스를 소유 할 수있는 유일한 방법입니다. 예를 들어, SOAP 표준은 http://www.w3.org/2003/05/soap-envelope 네임 스페이스를 사용하고 OpenDocument 파일은 (다른 것들 중에서) urn : oasis : names : tc : opendocument : xmlns : meta : 1.0을 사용합니다. . 질문의 예제는 http://example.com 및 https://namespaces.example.org/two 네임 스페이스를 사용합니다.

    문서 또는 문서의 섹션 내에서 네임 스페이스에는 콜론 앞에 표시되는 부분 인 로컬 접두사가 제공됩니다. 예를 들어, 다른 문서에서 SOAP 네임 스페이스에 로컬 접두사 ​​soap :, SOAP :, SOAP-ENV :, env : 또는 ns1 : 만 제공 될 수 있습니다. 이러한 이름은 특별한 xmlns 속성을 사용하여 네임 스페이스의 식별자로 다시 링크됩니다. xmlns : soap = "http://www.w3.org/2003/05/soap-envelope". 특정 문서의 접두사 선택은 완전히 임의적이며 의미를 변경하지 않고 생성 될 때마다 바뀔 수 있습니다.

    마지막으로, 각 문서 또는 문서의 섹션에 기본 네임 스페이스가 있는데, 이는 접두사가없는 요소에 사용되는 네임 스페이스입니다. xmlns 속성에 의해 다음과 같이 정의됩니다. xmlns = "http://www.w3.org/2003/05/soap-envelope". 위의 예에서 는 http://example.com으로 정의 된 기본 네임 스페이스에 있습니다.

    다소 특이하게 말하자면 접두어가 붙지 않은 속성은 기본 네임 스페이스에있는 것이 아니라 표준에서 명확하게 정의하지 않는 일종의 "무효 네임 스페이스"에 있습니다. 참조 : XML 네임 스페이스와 접두사가 붙지 않은 속성

    네임 스페이스가있는 SimpleXML 객체에서 print_r, var_dump 또는 이와 유사한 "dump structure"함수를 사용하면 일부 내용이 표시되지 않습니다. 그것은 여전히 ​​존재하며 아래에 설명 된대로 액세스 할 수 있습니다.

    SimpleXML은 네임 스페이스를 사용하는 두 가지 주요 방법을 제공합니다.

    이 두 메소드는 네임 스페이스 식별자를 첫 번째 인수로 사용합니다. 이러한 식별자는 다소 길기 때문에 작업중인 네임 스페이스를 나타내는 상수 또는 변수를 정의하는 것이 유용 할 수 있으므로 전체 URI 전체를 복사하여 붙여 넣지 않아도됩니다.

    예를 들어 위의 예는 다음과 같습니다.

    define('XMLNS_EG2', 'https://namespaces.example.org/two');
    define('XMLNS_SEQ', 'urn:example:sequences');
    foreach ( $sx->list->children(XMLNS_EG2)->item as $item ) {
        echo 'Position: ' . $item->attributes(XMLNS_SEQ)->position . "\n";
        echo 'Item: ' . (string)$item . "\n";
    }
    

    간단히 말해, 두 번째 매개 변수를 true로 지정하여 네임 스페이스의 로컬 별칭에 메서드를 전달할 수도 있습니다. 이 접두어는 언제든지 변경 될 수 있습니다. 예를 들어, 생성자가 접두사 ns1, ns2 등을 할당하고 코드가 약간 변경되면 다른 순서로 배정 할 수 있습니다. 이 짧은 - 손을 사용하여, 코드가 될 것이다 :

    foreach ( $sx->list->children('ns2', true)->item as $item ) {
        echo 'Position: ' . $item->attributes('seq', true)->position . "\n";
        echo 'Item: ' . (string)$item . "\n";
    }
    

    (이 짧은 핸드는 PHP 5.2에서 추가되었으며 $ sx-> getNamespaces를 사용하여 좀 더 긴 버전의 접두어 - 식별자 쌍 목록을 사용하여 실제로 오래된 예제를 볼 수 있습니다.)

  2. from https://stackoverflow.com/questions/44894426/reference-how-do-i-handle-namespaces-tags-and-attributes-with-colon-in-in-si by cc-by-sa and MIT license