복붙노트

PHP에서 XML을 JSON으로 변환

PHP

PHP에서 XML을 JSON으로 변환

PHP에서 json XML 변환하려고합니다. 간단한 xml 및 json_encode를 사용하여 간단한 변환을 수행하는 경우 XML 표시의 특성 중 하나도 표시되지 않습니다.

$xml = simplexml_load_file("states.xml");
echo json_encode($xml);

그래서 나는 이것을 수동으로 분석하려고합니다.

foreach($xml->children() as $state)
{
    $states[]= array('state' => $state->name); 
}       
echo json_encode($states);

{ "state": "Alabama"}가 아닌 { "state": { "0": "Alabama"}}

내가 도대체 ​​뭘 잘못하고있는 겁니까?

XML :

<?xml version="1.0" ?>
<states>
    <state id="AL">     
    <name>Alabama</name>
    </state>
    <state id="AK">
        <name>Alaska</name>
    </state>
</states>

산출:

[{"state":{"0":"Alabama"}},{"state":{"0":"Alaska"}

덤프 였어.

object(SimpleXMLElement)#1 (1) {
["state"]=>
array(2) {
[0]=>
object(SimpleXMLElement)#3 (2) {
  ["@attributes"]=>
  array(1) {
    ["id"]=>
    string(2) "AL"
  }
  ["name"]=>
  string(7) "Alabama"
}
[1]=>
object(SimpleXMLElement)#2 (2) {
  ["@attributes"]=>
  array(1) {
    ["id"]=>
    string(2) "AK"
  }
  ["name"]=>
  string(6) "Alaska"
}
}
}

해결법

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

    1.XML에서 Json & Array 3 행 :

    XML에서 Json & Array 3 행 :

    $xml = simplexml_load_string($xml_string);
    $json = json_encode($xml);
    $array = json_decode($json,TRUE);
    

    그래!

  2. ==============================

    2.오래된 게시물에 답변 해 주셔서 유감이지만,이 기사에서는 상대적으로 짧고, 간결하며 유지하기 쉬운 접근 방식에 대해 설명합니다. 나는 그것을 직접 테스트했고 꽤 잘 작동한다.

    오래된 게시물에 답변 해 주셔서 유감이지만,이 기사에서는 상대적으로 짧고, 간결하며 유지하기 쉬운 접근 방식에 대해 설명합니다. 나는 그것을 직접 테스트했고 꽤 잘 작동한다.

    http://lostechies.com/seanbiefeld/2011/10/21/simple-xml-to-json-with-php/

    <?php   
    class XmlToJson {
        public function Parse ($url) {
            $fileContents= file_get_contents($url);
            $fileContents = str_replace(array("\n", "\r", "\t"), '', $fileContents);
            $fileContents = trim(str_replace('"', "'", $fileContents));
            $simpleXml = simplexml_load_string($fileContents);
            $json = json_encode($simpleXml);
    
            return $json;
        }
    }
    ?>
    
  3. ==============================

    3.나는 그것을 알아. json_encode는 객체와 문자열을 다르게 처리합니다. 나는 객체를 문자열로 던져서 이제 작동합니다.

    나는 그것을 알아. json_encode는 객체와 문자열을 다르게 처리합니다. 나는 객체를 문자열로 던져서 이제 작동합니다.

    foreach($xml->children() as $state)
    {
        $states[]= array('state' => (string)$state->name); 
    }       
    echo json_encode($states);
    
  4. ==============================

    4.나는 파티에 조금 늦은 것 같지만이 일을 완수하기 위해 작은 기능을 썼다. 또한 특성, 텍스트 내용을 처리하며 노드 이름이 같은 여러 노드가 형제 노드 일 경우에도 마찬가지입니다.

    나는 파티에 조금 늦은 것 같지만이 일을 완수하기 위해 작은 기능을 썼다. 또한 특성, 텍스트 내용을 처리하며 노드 이름이 같은 여러 노드가 형제 노드 일 경우에도 마찬가지입니다.

    부인 성명: 나는 PHP 네이티브가 아니므로, 간단한 실수를 저 지르십시오.

    function xml2js($xmlnode) {
        $root = (func_num_args() > 1 ? false : true);
        $jsnode = array();
    
        if (!$root) {
            if (count($xmlnode->attributes()) > 0){
                $jsnode["$"] = array();
                foreach($xmlnode->attributes() as $key => $value)
                    $jsnode["$"][$key] = (string)$value;
            }
    
            $textcontent = trim((string)$xmlnode);
            if (count($textcontent) > 0)
                $jsnode["_"] = $textcontent;
    
            foreach ($xmlnode->children() as $childxmlnode) {
                $childname = $childxmlnode->getName();
                if (!array_key_exists($childname, $jsnode))
                    $jsnode[$childname] = array();
                array_push($jsnode[$childname], xml2js($childxmlnode, true));
            }
            return $jsnode;
        } else {
            $nodename = $xmlnode->getName();
            $jsnode[$nodename] = array();
            array_push($jsnode[$nodename], xml2js($xmlnode, true));
            return json_encode($jsnode);
        }
    }   
    

    사용 예 :

    $xml = simplexml_load_file("myfile.xml");
    echo xml2js($xml);
    

    예제 입력 (myfile.xml) :

    <family name="Johnson">
        <child name="John" age="5">
            <toy status="old">Trooper</toy>
            <toy status="old">Ultrablock</toy>
            <toy status="new">Bike</toy>
        </child>
    </family>
    

    예제 출력 :

    {"family":[{"$":{"name":"Johnson"},"child":[{"$":{"name":"John","age":"5"},"toy":[{"$":{"status":"old"},"_":"Trooper"},{"$":{"status":"old"},"_":"Ultrablock"},{"$":{"status":"new"},"_":"Bike"}]}]}]}
    

    예쁜 인쇄물 :

    {
        "family" : [{
                "$" : {
                    "name" : "Johnson"
                },
                "child" : [{
                        "$" : {
                            "name" : "John",
                            "age" : "5"
                        },
                        "toy" : [{
                                "$" : {
                                    "status" : "old"
                                },
                                "_" : "Trooper"
                            }, {
                                "$" : {
                                    "status" : "old"
                                },
                                "_" : "Ultrablock"
                            }, {
                                "$" : {
                                    "status" : "new"
                                },
                                "_" : "Bike"
                            }
                        ]
                    }
                ]
            }
        ]
    }
    

    명심할 것 : 같은 태그 네임을 가진 여러 태그가 형제가 될 수 있습니다. 다른 솔루션은 마지막 형제를 제외한 모든 솔루션을 드롭 할 가능성이 큽니다. 이를 피하기 위해 각각의 모든 단일 노드는 하나의 자식 만 가질지라도 태그의 각 인스턴스에 대해 객체를 보유하는 배열입니다. (예제에서 여러 ""요소 참조)

    유효한 XML 문서에 하나만 존재해야하는 루트 요소조차도 일관된 데이터 구조를 갖기 위해 인스턴스의 객체와 함께 배열로 저장됩니다.

    XML 노드 내용과 XML 속성을 구별 할 수 있도록 각 객체 속성은 "$"및 "_"하위의 내용에 저장됩니다.

    편집하다: 귀하의 예제 입력 데이터에 대한 출력을 표시하는 것을 잊었습니다.

    {
        "states" : [{
                "state" : [{
                        "$" : {
                            "id" : "AL"
                        },
                        "name" : [{
                                "_" : "Alabama"
                            }
                        ]
                    }, {
                        "$" : {
                            "id" : "AK"
                        },
                        "name" : [{
                                "_" : "Alaska"
                            }
                        ]
                    }
                ]
            }
        ]
    }
    
  5. ==============================

    5.이것을 사용해보십시오.

    이것을 사용해보십시오.

    $xml = ... // Xml file data
    
    // first approach
    $Json = json_encode(simplexml_load_string($xml));
    
    ---------------- OR -----------------------
    
    // second approach
    $Json = json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA));
    
    echo $Json;
    

    또는

    이 라이브러리를 사용할 수 있습니다 : https://github.com/rentpost/xml2array

  6. ==============================

    6.공통적 인 함정은 json_encode ()가 textvalue 및 attribute (s)를 가진 요소를 존중하지 않는다는 것을 잊는 것입니다. 데이터 로크를 의미하는 그 중 하나를 선택합니다. 아래 함수는이 문제를 해결합니다. json_encode / decode 방법을 사용하기로 결정하면 다음 함수를 사용하는 것이 좋습니다.

    공통적 인 함정은 json_encode ()가 textvalue 및 attribute (s)를 가진 요소를 존중하지 않는다는 것을 잊는 것입니다. 데이터 로크를 의미하는 그 중 하나를 선택합니다. 아래 함수는이 문제를 해결합니다. json_encode / decode 방법을 사용하기로 결정하면 다음 함수를 사용하는 것이 좋습니다.

    function json_prepare_xml($domNode) {
      foreach($domNode->childNodes as $node) {
        if($node->hasChildNodes()) {
          json_prepare_xml($node);
        } else {
          if($domNode->hasAttributes() && strlen($domNode->nodeValue)){
             $domNode->setAttribute("nodeValue", $node->textContent);
             $node->nodeValue = "";
          }
        }
      }
    }
    
    $dom = new DOMDocument();
    $dom->loadXML( file_get_contents($xmlfile) );
    json_prepare_xml($dom);
    $sxml = simplexml_load_string( $dom->saveXML() );
    $json = json_decode( json_encode( $sxml ) );
    

    이렇게하면 Lorem 은 JSON에서 { "foo": "Lorem"}으로 끝나지 않을 것입니다.

  7. ==============================

    7.최적화 안토니오 맥스 대답 :

    최적화 안토니오 맥스 대답 :

    $xmlfile = 'yourfile.xml';
    $xmlparser = xml_parser_create();
    
    // open a file and read data
    $fp = fopen($xmlfile, 'r');
    //9999999 is the length which fread stops to read.
    $xmldata = fread($fp, 9999999);
    
    // converting to XML
    $xml = simplexml_load_string($xmldata, "SimpleXMLElement", LIBXML_NOCDATA);
    
    // converting to JSON
    $json = json_encode($xml);
    $array = json_decode($json,TRUE);
    
  8. ==============================

    8.이 목적으로 Miles Johnson의 TypeConverter를 사용했습니다. Composer를 사용하여 설치할 수 있습니다.

    이 목적으로 Miles Johnson의 TypeConverter를 사용했습니다. Composer를 사용하여 설치할 수 있습니다.

    다음과 같이 작성할 수 있습니다.

    <?php
    require 'vendor/autoload.php';
    use mjohnson\utility\TypeConverter;
    
    $xml = file_get_contents("file.xml");
    $arr = TypeConverter::xmlToArray($xml, TypeConverter::XML_GROUP);
    echo json_encode($arr);
    
  9. ==============================

    9.XML의 특정 부분 만 JSON으로 변환하려면 XPath를 사용하여이 내용을 검색하고이를 JSON으로 변환 할 수 있습니다.

    XML의 특정 부분 만 JSON으로 변환하려면 XPath를 사용하여이 내용을 검색하고이를 JSON으로 변환 할 수 있습니다.

    <?php
    $file = @file_get_contents($xml_File, FILE_TEXT);
    $xml = new SimpleXMLElement($file);
    $xml_Excerpt = @$xml->xpath('/states/state[@id="AL"]')[0]; // [0] gets the node
    echo json_encode($xml_Excerpt);
    ?>
    

    Xpath가 올바르지 않으면 오류로 인해 사망합니다. 따라서 AJAX 호출을 통해 디버깅하는 경우 응답 본문도 기록하는 것이 좋습니다.

  10. ==============================

    10.이는 안토니오 맥스 (Antonio Max)가 가장 많이 언급 한 솔루션의 개선으로, 네임 스페이스가있는 XML에서도 작동합니다 (콜론을 밑줄로 대체 함). 또한 몇 가지 추가 옵션이 있습니다 ( John 을 올바르게 구문 분석합니다).

    이는 안토니오 맥스 (Antonio Max)가 가장 많이 언급 한 솔루션의 개선으로, 네임 스페이스가있는 XML에서도 작동합니다 (콜론을 밑줄로 대체 함). 또한 몇 가지 추가 옵션이 있습니다 ( John 을 올바르게 구문 분석합니다).

    function parse_xml_into_array($xml_string, $options = array()) {
        /*
        DESCRIPTION:
        - parse an XML string into an array
        INPUT:
        - $xml_string
        - $options : associative array with any of these keys:
            - 'flatten_cdata' : set to true to flatten CDATA elements
            - 'use_objects' : set to true to parse into objects instead of associative arrays
            - 'convert_booleans' : set to true to cast string values 'true' and 'false' into booleans
        OUTPUT:
        - associative array
        */
    
        // Remove namespaces by replacing ":" with "_"
        if (preg_match_all("|</([\\w\\-]+):([\\w\\-]+)>|", $xml_string, $matches, PREG_SET_ORDER)) {
            foreach ($matches as $match) {
                $xml_string = str_replace('<'. $match[1] .':'. $match[2], '<'. $match[1] .'_'. $match[2], $xml_string);
                $xml_string = str_replace('</'. $match[1] .':'. $match[2], '</'. $match[1] .'_'. $match[2], $xml_string);
            }
        }
    
        $output = json_decode(json_encode(@simplexml_load_string($xml_string, 'SimpleXMLElement', ($options['flatten_cdata'] ? LIBXML_NOCDATA : 0))), ($options['use_objects'] ? false : true));
    
        // Cast string values "true" and "false" to booleans
        if ($options['convert_booleans']) {
            $bool = function(&$item, $key) {
                if (in_array($item, array('true', 'TRUE', 'True'), true)) {
                    $item = true;
                } elseif (in_array($item, array('false', 'FALSE', 'False'), true)) {
                    $item = false;
                }
            };
            array_walk_recursive($output, $bool);
        }
    
        return $output;
    }
    
  11. ==============================

    11.$ state-> name 변수에 배열이있는 것 같습니다. 당신이 사용할 수있는

    $ state-> name 변수에 배열이있는 것 같습니다. 당신이 사용할 수있는

    var_dump($state)
    

    foreach 내부 테스트.

    이 경우 foreach 내부의 줄을 다음과 같이 변경할 수 있습니다.

    $states[]= array('state' => array_shift($state->name)); 
    

    그것을 수정하십시오.

  12. ==============================

    12.질문은 그것을 말하지 않지만, 일반적으로 PHP는 JSON을 웹 페이지로 반환합니다.

    질문은 그것을 말하지 않지만, 일반적으로 PHP는 JSON을 웹 페이지로 반환합니다.

    JS lib를 통해 브라우저 / 페이지에서 XML을 JSON으로 변환하는 것이 훨씬 쉽다는 것을 알게되었습니다. 예를 들면 다음과 같습니다.

    https://code.google.com/p/x2js/downloads/detail?name=x2js-v1.1.3.zip
    
  13. ==============================

    13.... 표현이 완벽한 XML 해석 (속성 문제없이)을 필요로하고 모든 텍스트 - 태그 - 텍스트 - 태그 - 텍스트 - 및 태그의 순서를 재현 할 때. 또한 JSON 객체가 "순서없는 세트"라는 것을 기억하십시오 (반복 키가 아니며 키에는 미리 정의 된 순서가있을 수 없음). 심지어 XML 구조를 정확하게 유지하지 않기 때문에 ZF의 xml2json이 잘못되었습니다 (!).

    ... 표현이 완벽한 XML 해석 (속성 문제없이)을 필요로하고 모든 텍스트 - 태그 - 텍스트 - 태그 - 텍스트 - 및 태그의 순서를 재현 할 때. 또한 JSON 객체가 "순서없는 세트"라는 것을 기억하십시오 (반복 키가 아니며 키에는 미리 정의 된 순서가있을 수 없음). 심지어 XML 구조를 정확하게 유지하지 않기 때문에 ZF의 xml2json이 잘못되었습니다 (!).

    모든 솔루션은이 간단한 XML에 문제가 있습니다.

        <states x-x='1'>
            <state y="123">Alabama</state>
            My name is <b>John</b> Doe
            <state>Alaska</state>
        </states>
    

    ... @FTav 솔루션은 3 라인 솔루션보다 좋지만이 XML로 테스트 할 때 약간의 버그가 있습니다.

    오늘날 jsonML로 잘 알려진이 솔루션은 Zorba 프로젝트 및 다른 사람들이 사용했으며, 2006 년 ~ 2007 년에 Stephen McKamey와 John Snelson이 (별도로) 발표했습니다.

    // the core algorithm is the XSLT of the "jsonML conventions"
    // see  https://github.com/mckamey/jsonml
    $xslt = 'https://raw.githubusercontent.com/mckamey/jsonml/master/jsonml.xslt';
    $dom = new DOMDocument;
    $dom->loadXML('
        <states x-x=\'1\'>
            <state y="123">Alabama</state>
            My name is <b>John</b> Doe
            <state>Alaska</state>
        </states>
    ');
    if (!$dom) die("\nERROR!");
    $xslDoc = new DOMDocument();
    $xslDoc->load($xslt);
    $proc = new XSLTProcessor();
    $proc->importStylesheet($xslDoc);
    echo $proc->transformToXML($dom);
    

    생기게 하다

    ["states",{"x-x":"1"},
        "\n\t    ",
        ["state",{"y":"123"},"Alabama"],
        "\n\t\tMy name is ",
        ["b","John"],
        " Doe\n\t    ",
        ["state","Alaska"],
        "\n\t"
    ]
    

    http://jsonML.org 또는 github.com/mckamey/jsonml을 참조하십시오. 이 JSON의 제작 규칙은 JSON-analog 요소를 기반으로하며,

    이 구문은 요소 정의 및 반복이며, element-list :: = element ','element-list | 요소.

  14. ==============================

    14.

    $xml = simplexml_load_string($xml_string);
    $json = json_encode($xml);
    $array = json_decode($json,TRUE);
    

    이 세 줄을 추가하면 정확한 결과를 얻을 수 있습니다 :-)

  15. ==============================

    15.약간의 답을 모두 조사한 후에 브라우저 (브라우저 / Dev 도구 포함)에서 자바 스크립트 기능을 사용하여 잘 작동하는 해결책을 찾았습니다.

    약간의 답을 모두 조사한 후에 브라우저 (브라우저 / Dev 도구 포함)에서 자바 스크립트 기능을 사용하여 잘 작동하는 해결책을 찾았습니다.

    <?php
    
     // PHP Version 7.2.1 (Windows 10 x86)
    
     function json2xml( $domNode ) {
      foreach( $domNode -> childNodes as $node) {
       if ( $node -> hasChildNodes() ) { json2xml( $node ); }
       else {
        if ( $domNode -> hasAttributes() && strlen( $domNode -> nodeValue ) ) {
         $domNode -> setAttribute( "nodeValue", $node -> textContent );
         $node -> nodeValue = "";
        }
       }
      }
     }
    
     function jsonOut( $file ) {
      $dom = new DOMDocument();
      $dom -> loadXML( file_get_contents( $file ) );
      json2xml( $dom );
      header( 'Content-Type: application/json' );
      return str_replace( "@", "", json_encode( simplexml_load_string( $dom -> saveXML() ), JSON_PRETTY_PRINT ) );
     }
    
     $output = jsonOut( 'https://boxelizer.com/assets/a1e10642e9294f39/b6f30987f0b66103.xml' );
    
     echo( $output );
    
     /*
      Or simply 
      echo( jsonOut( 'https://boxelizer.com/assets/a1e10642e9294f39/b6f30987f0b66103.xml' ) );
     */
    
    ?>
    

    그것은 기본적으로 새로운 DOMDocument를 생성하고, XML 파일을로드하고, 데이터 / 매개 변수를 가져 와서 성가신 "@"기호없이 JSON으로 내보내는 노드와 자식 각각을 통과합니다.

    XML 파일에 링크하십시오.

  16. ==============================

    16.

    $templateData =  $_POST['data'];
    
    // initializing or creating array
    $template_info =  $templateData;
    
    // creating object of SimpleXMLElement
    $xml_template_info = new SimpleXMLElement("<?xml version=\"1.0\"?><template></template>");
    
    // function call to convert array to xml
    array_to_xml($template_info,$xml_template_info);
    
    //saving generated xml file
     $xml_template_info->asXML(dirname(__FILE__)."/manifest.xml") ;
    
    // function defination to convert array to xml
    function array_to_xml($template_info, &$xml_template_info) {
        foreach($template_info as $key => $value) {
            if(is_array($value)) {
                if(!is_numeric($key)){
                    $subnode = $xml_template_info->addChild($key);
                    if(is_array($value)){
                        $cont = 0;
                        foreach(array_keys($value) as $k){
                            if(is_numeric($k)) $cont++;
                        }
                    }
    
                    if($cont>0){
                        for($i=0; $i < $cont; $i++){
                            $subnode = $xml_body_info->addChild($key);
                            array_to_xml($value[$i], $subnode);
                        }
                    }else{
                        $subnode = $xml_body_info->addChild($key);
                        array_to_xml($value, $subnode);
                    }
                }
                else{
                    array_to_xml($value, $xml_template_info);
                }
            }
            else {
                $xml_template_info->addChild($key,$value);
            }
        }
    }
    
  17. from https://stackoverflow.com/questions/8830599/php-convert-xml-to-json by cc-by-sa and MIT license