PHP XML को JSON में बदल देती है


158

मैं xml को jp में php में बदलने की कोशिश कर रहा हूँ। अगर मैं साधारण 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":{"0":"Alabama"}}बजाय है{"state":"Alabama"}

मैं क्या गलत कर रहा हूं?

एक्सएमएल:

<?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"}

var डंप:

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"
}
}
}

कृपया पार्स करने के बाद XML की एक स्निपेट और अंतिम सरणी संरचना को शामिल करें। (एक var_dumpकाम ठीक है।)
nikc.org

जोड़ा इनपुट, आउटपुट और var_dump
ब्रायन हैडलॉक

कुछ अनुप्रयोगों को "perfec XML-to-JSON मैप" की आवश्यकता होती है , जो कि jsonML है , यहां समाधान देखें ।
पीटर क्रूस

जवाबों:


472

3 लाइनों में XML से Json और ऐरे:

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

58
यह समाधान निर्दोष नहीं है। यह पूरी तरह से XML विशेषताओं को छोड़ देता है। तो के <person my-attribute='name'>John</person>रूप में व्याख्या की है <person>John</person>
जेक विल्सन

13
$ xml = simplexml_load_string ($ xml_string, 'SimpleXMLElement', LIBXML_NOCDATA); cdata तत्वों को समतल करने के लिए।
txyoji

28
@JakeWilson को शायद 2 साल बीत चुके हैं, और विभिन्न संस्करण ठीक हो गए हैं, लेकिन PHP 5.6.30 पर, यह विधि सभी डेटा का उत्पादन करती है। विशेषताएँ @attributesकुंजी के तहत सरणी में संग्रहीत की जाती हैं , इसलिए यह बिल्कुल निर्दोष रूप से, और खूबसूरती से काम करती है। कोड की 3 छोटी लाइनें मेरी समस्या को खूबसूरती से हल करती हैं।
अलेक्जेंडर

1
यह काम नहीं करता है यदि आपके पास कई नामस्थान हैं, तो आप केवल एक चुन सकते हैं, जो $ json_string में पास होगा: '(
jirislav

1
ध्यान रखें कि इस समाधान के साथ, जब एक ही नाम के साथ कई नोड्स हो सकते हैं, तो एक नोड में एक तत्व की ओर इशारा करते हुए एक कुंजी होगी, लेकिन कई नोड्स तत्वों के सरणी की ओर इंगित करने में महत्वपूर्ण होंगे : <list><item><a>123</a><a>456</a></item><item><a>123</a></item></list>-> {"item":[{"a":["123","456"]},{"a":"123"}]}चूहे के द्वारा php.net पर एक समाधान एक सरणी में हमेशा तत्वों को संग्रहीत करके उस मुद्दे को हल करता है।
क्लेसुन

37

एक पुरानी पोस्ट का जवाब देने के लिए क्षमा करें, लेकिन यह लेख एक दृष्टिकोण को रेखांकित करता है जो अपेक्षाकृत संक्षिप्त, संक्षिप्त और बनाए रखने में आसान है। मैंने इसे खुद परखा और बहुत अच्छा काम किया।

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;
    }
}
?>

4
यह काम नहीं करेगा यदि आपके XML में एक ही टैग के कई उदाहरण हैं, तो json_encode केवल टैग के अंतिम उदाहरण को क्रमबद्ध करेगा।
एथ्री

35

मैं यह समझ गया। json_encode वस्तुओं को स्ट्रिंग्स की तुलना में अलग तरीके से हैंडल करता है। मैंने एक स्ट्रिंग को ऑब्जेक्ट डाला और यह अब काम करता है।

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

19

मुझे लगता है कि मुझे पार्टी में थोड़ी देर हो गई है लेकिन मैंने इस कार्य को पूरा करने के लिए एक छोटा सा कार्य लिखा है। इसमें विशेषताओं, पाठ सामग्री और यहां तक ​​कि एक ही नोड-नाम वाले कई नोड्स भाई-बहन होने पर भी ध्यान रखा जाता है।

अस्वीकरण: मैं एक 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"
                        }
                    ]
                }
            ]
        }
    ]
}

ध्यान में रखने की Quirks: एक ही tagname वाले कई टैग्स भाई-बहन हो सकते हैं। अन्य समाधान सबसे अधिक संभावना है, लेकिन अंतिम भाई-बहन को छोड़ देंगे। इस एक-एक नोड से बचने के लिए, भले ही इसका केवल एक ही बच्चा हो, एक ऐसा सरणी है जो टैग्नैम के प्रत्येक उदाहरण के लिए एक ऑब्जेक्ट रखता है। (उदाहरण में कई "" तत्व देखें)

यहां तक ​​कि रूट तत्व, जिनमें से केवल एक वैध एक्सएमएल दस्तावेज़ में मौजूद होना चाहिए, उदाहरण के लिए ऑब्जेक्ट के साथ सरणी के रूप में संग्रहीत किया जाता है, बस एक सुसंगत डेटा संरचना होना चाहिए।

XML नोड सामग्री और XML विशेषताओं के बीच अंतर करने में सक्षम होने के लिए प्रत्येक ऑब्जेक्ट विशेषताओं को "$" और "_" बच्चे की सामग्री में संग्रहीत किया जाता है।

संपादित करें: मैं आपके उदाहरण इनपुट डेटा के लिए आउटपुट दिखाना भूल गया

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

क्या यह बड़े XML डेटा को पार्स कर सकता है?
वोलेटिल 3

2
यह समाधान बेहतर है क्योंकि XML विशेषताओं को नहीं छोड़ता है। यह भी देखें कि यह जटिल संरचना सरलीकृत लोगों की तुलना में बेहतर क्यों है, xml.com/lpt/a/1658 पर (देखें "सेमी-स्ट्रक्चर्ड XML") .... Ops, CDATA के लिए, जैसा कि @txyoji ने सीडीआर तत्वों को समतल करने का सुझाव दिया है $xml = simplexml_load_file("myfile.xml",'SimpleXMLElement',LIBXML_‌​NOCDATA);
पीटर क्रस

एक कस्टम फ़ंक्शन के लिए बहुत धन्यवाद! यह ट्यूनिंग को बहुत आसान बनाता है। Btw, ने आपके फ़ंक्शन का एक संपादित संस्करण जोड़ा, जो XML को JS तरीके से पार्स करता है: प्रत्येक प्रविष्टि की अपनी वस्तु होती है (यदि वे समान tagnames हैं तो प्रविष्टियां एकल सरणी में संग्रहीत नहीं होती हैं), इस प्रकार ऑर्डर संरक्षित है।
लूसिफ़ेर 63

1
त्रुटि Fatal error: Uncaught Error: Call to a member function getName() on bool.. मुझे लगता है कि एक संस्करण php विफल है :-( .. कृपया मदद!
KingRider

10

एक सामान्य json_encode()नुकसान यह है कि एक पाठ और विशेषता (एस) के साथ तत्वों का सम्मान नहीं करना है । यह उनमें से एक का चयन करेगा, जिसका अर्थ है डटलॉस। नीचे दिया गया कार्य उस समस्या को हल करता है। यदि कोई 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 ) );

ऐसा करने से, आपके JSON में <foo bar="3">Lorem</foo>समाप्त नहीं होगा {"foo":"Lorem"}


संकलित-त्रुटियों को ठीक किए जाने पर वर्णित आउटपुट का संकलन और उत्पादन नहीं करता है।
रिचर्ड कीफर

क्या है $dom? वह कहां से आया है?
जेक विल्सन

$ डोम = नया DOMDocument (); वह कहाँ से आता है
स्कॉट

1
कोड की अंतिम पंक्ति: $ json = json_decode (json_encode ($ sxml))); होना चाहिए: $ json = json_decode (json_encode ($ sxml));
चार्ली स्मिथ

6

इसका उपयोग करने का प्रयास करें

$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


3

मैंने इस उद्देश्य के लिए माइल्स जॉनसन के टाइपकॉन्सर का उपयोग किया है । यह कम्पोजर का उपयोग कर स्थापित करने योग्य है ।

आप इसका उपयोग करके कुछ ऐसा लिख ​​सकते हैं:

<?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);

3

ऑप्टिमाइज़िंग एंटोनियो मैक्स उत्तर:

$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);

4
मैंने इस दृष्टिकोण का उपयोग किया है, लेकिन JSON खाली है। XML मान्य है।
रायबेंको-प्रो

2

यदि आप 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 कॉल के माध्यम से यह डिबग कर रहे हैं तो मैं आपको प्रतिक्रिया निकायों को भी लॉग इन करने की सलाह देता हूं।


2
This is better solution

$fileContents= file_get_contents("https://www.feedforall.com/sample.xml");
$fileContents = str_replace(array("\n", "\r", "\t"), '', $fileContents);
$fileContents = trim(str_replace('"', "'", $fileContents));
$simpleXml = simplexml_load_string($fileContents);
$json = json_encode($simpleXml);
$array = json_decode($json,TRUE);
return $array;

2

सबसे अच्छा समाधान जो एक आकर्षण की तरह काम करता है

$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); // Remove // if you want to store the result in $json variable

echo '<pre>'.json_encode($simpleXml,JSON_PRETTY_PRINT).'</pre>';

स्रोत


1

यह एंटोनियो मैक्स द्वारा सबसे उत्कीर्ण समाधान का एक सुधार है, जो एक्सएमएल के साथ भी काम करता है जिसमें नेमस्पेस (कोलोन को अंडरस्कोर के साथ बदलकर) है। इसमें कुछ अतिरिक्त विकल्प भी हैं (और <person my-attribute='name'>John</person>सही तरीके से पार्स करता है)।

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;
}

2
XML को पार्स करने के लिए रेगेक्स का उपयोग नहीं किया जाता है, जब तक कि यह एक सामान्य XML नहीं है, जिसमें तुच्छ संरचना और बहुत अनुमानित डेटा है। मैं पर्याप्त तनाव नहीं कर सकता कि यह समाधान कितना बुरा है। यह ब्रेक डेटा। यह उल्लेख करने के लिए नहीं कि यह अविश्वसनीय रूप से धीमा है (आप रेगेक्स के साथ पार्स करते हैं, और फिर आप फिर से पार्स करते हैं?) और स्व-समापन टैग को नहीं संभालते हैं।
अलेक्जेंडर

मुझे नहीं लगता कि आपने वास्तव में समारोह को देखा। यह वास्तविक पार्सिंग करने के लिए रेगेक्स का उपयोग नहीं करता है, केवल नामस्थान से निपटने के लिए एक साधारण फिक्स के रूप में - जो मेरे सभी xml मामलों के लिए काम कर रहा है - और यह कि यह काम कर रहा है "राजनीतिक रूप से सही" होने के बजाय सबसे महत्वपूर्ण है। यदि आप चाहें, तो इसे बेहतर बनाने के लिए आपका स्वागत है!
TheStoryCoder 21

2
तथ्य यह है कि यह आपके लिए काम किया है इसका मतलब यह नहीं है कि यह सही है। यह इस तरह का कोड है जो बग उत्पन्न करता है जो निदान के लिए बहुत कठिन हैं, और शोषण उत्पन्न करता है। मेरा मतलब है कि इस w3schools.com/xml/xml_elements.asp जैसी साइटों पर XML ऐनक पर सतही रूप से देखने के कारण बहुत सारे कारण बताते हैं कि यह समाधान काम क्यों नहीं करेगा। जैसा कि मैंने कहा, यह स्व-समापन टैग का पता लगाने में विफल रहता है जैसे <element/>, उन तत्वों को संबोधित करने में विफल रहता है, जो शुरू होते हैं, या अंडरस्कोर होते हैं, जो XML में अनुमत है। CDATA का पता लगाने में विफल। और जैसा कि मैंने कहा है, यह धीमी है। आंतरिक पार्सिंग के कारण यह O (n ^ 2) जटिलता है।
एलेक्जेंडरएमपी

1
बात यह है कि यहाँ नामस्थानों के साथ काम भी नहीं पूछा गया था, और नामस्थानों से निपटने के लिए संभावित तरीके हैं। Namespaces एक सहायक निर्माण के रूप में मौजूद है, इस तरह से पार्स नहीं किया जा सकता है और एक घृणा में बदल गया है जिसे किसी भी उचित पार्सर द्वारा संसाधित नहीं किया जाएगा। और इसके लिए आपको बस इतना करना चाहिए कि "2016 के सबसे धीमे एल्गोरिदम" के पुरस्कार के लिए दावेदार न बनाएं, लेकिन थोड़ी खोज करने के लिए, वास्तविक समाधानों के असंख्य के साथ आने के लिए, जैसे कि यह एक stackoverflow.com/ प्रश्न / 16412047 /… और इसे सुधार के लिए कहते हैं? वाह।
एलेक्जेंडरएमपी

0

यहां सभी समाधानों में समस्याएं हैं!

... जब प्रतिनिधित्व को सही XML व्याख्या (विशेषताओं के साथ समस्याओं के बिना) और सभी पाठ-टैग-पाठ-टैग-पाठ -... और टैग के क्रम को पुन: पेश करने की आवश्यकता होती है। यहां यह भी याद रखें कि JSON ऑब्जेक्ट "एक अनियंत्रित सेट" है (रिपीट कीज़ नहीं और कीज़ का पूर्वनिर्धारित क्रम नहीं हो सकता है) ... यहां तक ​​कि ZF का xml2json गलत है (!) क्योंकि XML संरचना को बिल्कुल संरक्षित नहीं करता है।

यहां सभी समाधानों में इस सरल XML के साथ समस्याएं हैं,

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

... @ एफटीएवी समाधान 3-लाइन समाधान से बेहतर लगता है, लेकिन इस एक्सएमएल के साथ परीक्षण किए जाने पर थोड़ा बग भी है।

पुराना समाधान सबसे अच्छा है (हानि-कम प्रतिनिधित्व के लिए)

समाधान, जिसे आज jsonML के रूप में जाना जाता है , का उपयोग ज़ोरबा परियोजना और अन्य लोगों द्वारा किया जाता है , और इसे पहली बार ~ 2006 या ~ 2007 में (अलग-अलग) स्टीफन मैककेमी और जॉन स्नेलसन द्वारा प्रस्तुत किया गया था ।

// 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-एनालॉग के तत्व पर आधारित हैं ,

यहां छवि विवरण दर्ज करें

यह सिंटैक्स एक तत्व परिभाषा और पुनरावृत्ति है, जिसके साथ
element-list ::= element ',' element-list | element


2
बहुत ही असामान्य xml संरचना जो मुझे संदेह है कि वास्तविक जीवन में उपयोग के मामले होंगे।
TheStoryCoder

0

सभी उत्तरों के बारे में थोड़ा शोध करने के बाद, मैं एक समाधान लेकर आया जो मेरे जावास्क्रिप्ट फ़ंक्शंस पर ब्राउज़रों (कंसोल / देव उपकरण सहित) के साथ ठीक काम करता है:

<?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 फ़ाइल से लिंक करें ।


0

यह समाधान नामस्थानों, विशेषताओं को संभालता है, और दोहराए जाने वाले तत्वों के साथ सुसंगत परिणाम पैदा करता है (हमेशा सरणी में, भले ही केवल एक ही घटना हो)। रैफैक्टर के sxiToArray () से प्रेरित है ।

/**
 * <root><a>5</a><b>6</b><b>8</b></root> -> {"root":[{"a":["5"],"b":["6","8"]}]}
 * <root a="5"><b>6</b><b>8</b></root> -> {"root":[{"a":"5","b":["6","8"]}]}
 * <root xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><a>123</a><wsp:b>456</wsp:b></root> 
 *   -> {"root":[{"xmlns:wsp":"http://schemas.xmlsoap.org/ws/2004/09/policy","a":["123"],"wsp:b":["456"]}]}
 */
function domNodesToArray(array $tags, \DOMXPath $xpath)
{
    $tagNameToArr = [];
    foreach ($tags as $tag) {
        $tagData = [];
        $attrs = $tag->attributes ? iterator_to_array($tag->attributes) : [];
        $subTags = $tag->childNodes ? iterator_to_array($tag->childNodes) : [];
        foreach ($xpath->query('namespace::*', $tag) as $nsNode) {
            // the only way to get xmlns:*, see https://stackoverflow.com/a/2470433/2750743
            if ($tag->hasAttribute($nsNode->nodeName)) {
                $attrs[] = $nsNode;
            }
        }

        foreach ($attrs as $attr) {
            $tagData[$attr->nodeName] = $attr->nodeValue;
        }
        if (count($subTags) === 1 && $subTags[0] instanceof \DOMText) {
            $text = $subTags[0]->nodeValue;
        } elseif (count($subTags) === 0) {
            $text = '';
        } else {
            // ignore whitespace (and any other text if any) between nodes
            $isNotDomText = function($node){return !($node instanceof \DOMText);};
            $realNodes = array_filter($subTags, $isNotDomText);
            $subTagNameToArr = domNodesToArray($realNodes, $xpath);
            $tagData = array_merge($tagData, $subTagNameToArr);
            $text = null;
        }
        if (!is_null($text)) {
            if ($attrs) {
                if ($text) {
                    $tagData['_'] = $text;
                }
            } else {
                $tagData = $text;
            }
        }
        $keyName = $tag->nodeName;
        $tagNameToArr[$keyName][] = $tagData;
    }
    return $tagNameToArr;
}

function xmlToArr(string $xml)
{
    $doc = new \DOMDocument();
    $doc->loadXML($xml);
    $xpath = new \DOMXPath($doc);
    $tags = $doc->childNodes ? iterator_to_array($doc->childNodes) : [];
    return domNodesToArray($tags, $xpath);
}

उदाहरण:

php > print(json_encode(xmlToArr('<root a="5"><b>6</b></root>')));
{"root":[{"a":"5","b":["6"]}]}

यह वास्तव में मल्टी-नेमस्पेस मामलों के लिए काम करता है, अन्य समाधानों की तुलना में बेहतर है, नीचे वोट क्यों मिला ...
ऐरन

0

मिला FTav का जवाब सबसे उपयोगी है क्योंकि यह बहुत ही अनुकूलन योग्य है, लेकिन उनके xml2js फ़ंक्शन में कुछ खामियां हैं। उदाहरण के लिए, यदि बच्चों के तत्वों में समान तगण होते हैं, तो वे सभी एक ही वस्तु में संग्रहीत किए जाएंगे, इसका मतलब है कि तत्वों का क्रम संरक्षित नहीं होगा। कुछ मामलों में हम वास्तव में ऑर्डर को संरक्षित करना चाहते हैं, इसलिए हम हर तत्व के डेटा को एक अलग ऑब्जेक्ट में बेहतर स्टोर करते हैं:

function xml2js($xmlnode) {
    $jsnode = array();
    $nodename = $xmlnode->getName();
    $current_object = array();

    if (count($xmlnode->attributes()) > 0) {
        foreach($xmlnode->attributes() as $key => $value) {
            $current_object[$key] = (string)$value;
        }
    }

    $textcontent = trim((string)$xmlnode);
    if (strlen($textcontent) > 0) {
        $current_object["content"] = $textcontent;
    }

    if (count($xmlnode->children()) > 0) {
        $current_object['children'] = array();
        foreach ($xmlnode->children() as $childxmlnode) {
            $childname = $childxmlnode->getName();
            array_push($current_object['children'], xml2js($childxmlnode, true));
        }
    }

    $jsnode[ $nodename ] = $current_object;
    return $jsnode;
}

यहाँ दिया गया है कि यह कैसे काम करता है। प्रारंभिक xml संरचना:

<some-tag some-attribute="value of some attribute">
  <another-tag>With text</another-tag>
  <surprise></surprise>
  <another-tag>The last one</another-tag>
</some-tag>

परिणाम JSON:

{
    "some-tag": {
        "some-attribute": "value of some attribute",
        "children": [
            {
                "another-tag": {
                    "content": "With text"
                }
            },
            {
                "surprise": []
            },
            {
                "another-tag": {
                    "content": "The last one"
                }
            }
        ]
    }
}

-1

लगता है कि $state->nameचर एक सरणी को पकड़े हुए है। आप उपयोग कर सकते हैं

var_dump($state)

foreachपरीक्षण करने के लिए अंदर ।

अगर ऐसी बात है, तो आप के अंदर लाइन को बदल सकते हैं foreachकरने के लिए

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

इसे ठीक करने के लिए।


ऐसा लगता है कि विशेषताएँ सरणियाँ हैं, लेकिन $ स्थिति नहीं-> नाम
ब्रायन हैडलॉक

-1
$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);
        }
    }
}

यह एक छोटा और सार्वभौमिक समाधान है, डेटा की एक सरणी पर आधारित एक JSON रूपांतरित json_decode हो सकता है ... भाग्यशाली
Octavio Perez Gallegos

2
यह किस तरह से मूल प्रश्न का उत्तर देता है? आपका उत्तर मूल प्रश्न की तुलना में अधिक जटिल लगता है, और कहीं भी JSON का उल्लेख नहीं करता है।
दान आर

-1

यदि आप ubuntu उपयोगकर्ता हैं तो xml रीडर स्थापित करें (मेरे पास php 5.6 है। यदि आपके पास कोई अन्य पैकेज है और इंस्टॉल करें)

sudo apt-get install php5.6-xml
service apache2 restart

$fileContents = file_get_contents('myDirPath/filename.xml');
$fileContents = str_replace(array("\n", "\r", "\t"), '', $fileContents);
$fileContents = trim(str_replace('"', "'", $fileContents));
$oldXml = $fileContents;
$simpleXml = simplexml_load_string($fileContents);
$json = json_encode($simpleXml);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.