<?PHP

#
#   FILE:  SPT--XMLStream.php
#
#   METHODS PROVIDED:
#       XMLStream($StartingIndentLevel = 0, $IndentSize = 4)
#           - constructor
#       AddElement($Name = NULL, $Content = NULL, $Attributes = NULL)
#           - add element (i.e. tag) to XML stream
#       OpenElement($Name, $Attributes = NULL)
#           - open new element in XML stream
#       CloseElement()
#           - close current element in XML stream
#       GetContent()
#           - return current stream content
#       ClearContent()
#           - clear current stream content
#       IndentLevel($NewIndentLevel = NULL)
#           - get/set current indent level
#       IndentSize($NewIndentSize = NULL)
#           - get/set current indent size
#
#   AUTHOR:  Edward Almasy
#
#   Part of the Scout Portal Toolkit
#   Copyright 2003-2004 Internet Scout Project
#   http://scout.wisc.edu
#

class XMLStream {

    # ---- PUBLIC INTERFACE --------------------------------------------------

    # object constructor
    function XMLStream($StartingIndentLevel = 0, $IndentSize = 4)
    {
        # initialize stack used to track open elements
        $this->OpenTagStack = array();

        # initialize current stream content
        $this->Stream = "<?xml version=\"1.0\"?>\n";

        # initialize current indent level and size
        $this->CurrentIndentLevel = $StartingIndentLevel;
        $this->CurrentIndentSize = $IndentSize;
    }

    # add element (i.e. tag) to XML stream
    function AddElement($Name = SCOUTXMLSTREAMNULLVALUE, $Content = SCOUTXMLSTREAMNULLVALUE, $Attributes = SCOUTXMLSTREAMNULLVALUE)
    {
        # if tag name supplied
        if ($Name !== SCOUTXMLSTREAMNULLVALUE)
        {
            # start out with appropriate indent
            $Tag = str_repeat(" ", ($this->CurrentIndentLevel * $this->CurrentIndentSize));

            # open begin tag
            $Tag .= "<".$Name;

            # if attributes supplied
            if ($Attributes !== SCOUTXMLSTREAMNULLVALUE)
            {
                # add attributes
                foreach ($Attributes as $AttributeName => $AttributeValue)
                {
                    $Tag .= " ".$AttributeName."=\"".$AttributeValue."\"";
                }
            }

            # if content supplied or we are assuming tag content
            if ($Content !== SCOUTXMLSTREAMNULLVALUE)
            {
                # close begin tag
                $Tag .= ">";

                # add content
                if ($Content !== NULL)
                {
                    $Tag .= htmlspecialchars($Content);
                }

                # add end tag
                $Tag .= "</".$Name.">\n";
            }
            else
            {
                # close begin tag
                $Tag .= ">\n";

                # increase indent level
                $this->CurrentIndentLevel++;

                # add tag to open tag stack
                array_push($this->OpenTagStack, $Name);
            }
        }
        else
        {
            # decrease indent level
            if ($this->CurrentIndentLevel > 0) {  $this->CurrentIndentLevel--;  }

            # pop last entry off of open tag stack
            $LastName = array_pop($this->OpenTagStack);

            # start out with appropriate indent
            $Tag = str_repeat(" ", ($this->CurrentIndentLevel * $this->CurrentIndentSize));

            # add end tag to match last open tag
            $Tag .= "</".$LastName.">\n";
        }

        # add formatted tag to stream
        $this->Stream .= $Tag;
    }

    # open new element in XML stream
    function OpenElement($Name, $Attributes = SCOUTXMLSTREAMNULLVALUE)
    {
        $this->AddElement($Name, SCOUTXMLSTREAMNULLVALUE, $Attributes);
    }

    # close current element in XML stream
    function CloseElement()
    {
        $this->AddElement();
    }

    # return current stream content
    function GetContent()
    {
        return $this->Stream;
    }

    # clear current stream content
    function ClearContent()
    {
        $this->Stream = "";
    }

    # get/set current indent level
    function IndentLevel($NewIndentLevel = NULL)
    {
        # if new indent level supplied
        if ($NewIndentLevel !== NULL)
        {
            # reset indent to requested level
            $this->CurrentIndentLevel = $NewIndentLevel;
        }

        # return current indent level to caller
        return $this->CurrentIndentLevel;
    }

    # get/set current indent size
    function IndentSize($NewIndentSize = NULL)
    {
        # if new indent size supplied
        if ($NewIndentSize !== NULL)
        {
            # reset indent to requested size
            $this->CurrentIndentSize = $NewIndentSize;
        }

        # return current indent size to caller
        return $this->CurrentIndentSize;
    }


    # ---- PRIVATE INTERFACE -------------------------------------------------

    var $CurrentIndentLevel;
    var $CurrentIndentSize;
    var $OpenTagStack;
    var $Stream;
}

define("SCOUTXMLSTREAMNULLVALUE", "X-SCOUT_XML_STREAM_NULL_VALUE-X");


?>
