Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
97 views
in Technique[技术] by (71.8m points)

php - how to structure an xml file in the form of a list of elements

here is part of my xml file

<?xml version="1.0" encoding="ISO-8859-1" ?>
    <stati_team>         
                <team>
                    <team>Bayern Munich</team>
                    <victory>10</victory>
                    <loss>2</loss>
                    <ranking>1</ranking>
                </team>   
                <team>
                    <team>RB Leipzig</team>
                    <victory>8</victory>
                    <loss>4</loss>
                    <ranking>2</ranking>
                </team>
    </stati_team>

my goal is to display the xml file as the browser does here is my php code he work without any problem

<?php
$file = "team.xml";
$depth = 0;
        function startElement($parser, $name, $attrs){
            global $depth;
            $depth++;
            print"<br>";
        for ($i = 0; $i < $depth; $i++) {
            print "&nbsp;&nbsp;&nbsp;"; 
        }
            print "&lt;<font color="#0000cc">$name</font>
";
            print"&gt;";
        }
        function endElement($parser, $name){
            global $depth;
            $depth--;
        for ($i=0; $i <$depth ; $i++) { 
            print "&nbsp;&nbsp;&nbsp;";
        }
            print "&lt;<font color="#0000cc">/$name</font>";print "&gt;<br>";
    }
function characterData($parser,$data){
    global $depth;
 for ($i = 0; $i < $depth; $i++) {
 print "&nbsp;&nbsp;&nbsp;";
    }
    print "$data";
}
$xml_parser=xml_parser_create();
    xml_set_element_handler($xml_parser,"startElement","endElement");
    xml_set_character_data_handler($xml_parser,"characterData");
    if(!($fp=fopen($file,"r"))){
        die("File XML: error");
    }
    while($data=fread($fp,4096)){
    if(!xml_parse($xml_parser,$data,feof($fp))){
    die("Error XML, ligne".xml_get_current_line_number($xml_parser)." !!!");
        }
    }
    xml_parser_free($xml_parser);
?>

output

outputxml

the output of the XML file is not bad. So my question is how we do so that the <team> tag is at the same level as </team> tag

question from:https://stackoverflow.com/questions/65850598/how-to-structure-an-xml-file-in-the-form-of-a-list-of-elements

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I fear that you do not fully understand what the functions are doing. Try to look at my solution and the respective functions in the php manual and hopefully it will be a bit clearer. if not add a comment as I now know and understand these functions, I have never heard about before today.

Here is the solution: To show what it does i have used "+" and "*" instead of non breaking spaces.

The original had unfortunately a lot of problems i fixed now. One example were the spaces inside the tags.

I changed the following things:

removed the unnecessary stuff inside the characterdate function. This function is only thought to print out the content between the tags - you do not want any additional stuff here!

Then I added a new global var $lastaction which stores the type of the last tag (start or end).
And now comes the critical part that took you 9 hours: If the last tag was an end tag we need to indent the tag for the number of levels. Thats it. So easy. But it also took me some time to get that super simple solution. :-/

I also added an if in the start tag to remove the break if the last tag was an end tag. because that looked wrong and not like your example. I also replaced the gruesome for(echo) loops with str_repeat()

 <?php
    $file = "team.xml";
    $depth = 0;
    $lastaction="";
    function startElement($parser, $name, $attrs){
        global $depth,$lastaction;
        $depth++;
        if ($lastaction!="end") print"<br>";
        echo str_repeat('++', $depth);
        print "<<font color="#0000cc">$name</font>>";
        $lastaction="start";
    }
    function endElement($parser, $name){
        global $depth, $lastaction;
        if ($lastaction=="end") echo str_repeat('**',$depth);
        $depth--;
        print "<<font color="#0000cc">/$name</font>><br>";
     $lastaction ="end";
    }
    function characterData($parser,$data){
        print  $data;
    }
    $xml_parser=xml_parser_create();
    xml_set_element_handler($xml_parser,"startElement","endElement");
    xml_set_character_data_handler($xml_parser,"characterData");
    if(!($fp=fopen($file,"r"))){
        die("File XML: error");
    }
    while($data=fread($fp,4096)){
        if(!xml_parse($xml_parser,$data,feof($fp))){
            die("Error XML, ligne".xml_get_current_line_number($xml_parser)." !!!");
        }
    }
    xml_parser_free($xml_parser);
    ?>

RESULT exactly as it should be (the * and + are only for demonstration because they are added in two different functions so you should understand what is happening here - replace them by one or more non breaking spaces and your homework is finished. ;-)

+<STATI_TEAM>
++<TEAM>
+++<TEAM>Bayern Munich</TEAM>
+++<VICTORY>10</VICTORY>
+++<LOSS>2</LOSS>
+++<RANKING>1</RANKING>
**</TEAM>
++<TEAM>
+++<TEAM>RB Leipzig</TEAM>
+++<VICTORY>8</VICTORY>
+++<LOSS>4</LOSS>
+++<RANKING>2</RANKING>
**</TEAM>
*</STATI_TEAM>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...