Generic Function for differing XML structure

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • code green
    Recognized Expert Top Contributor
    • Mar 2007
    • 1726

    #1

    Generic Function for differing XML structure

    I have written code that accepts orders then writes them to XML.
    I can create two formats of XML, one is bespoke to our CRM, the other is opXML under BOSS standards.

    My final createXML function is entirely different for each format because the structure and element names differ.
    Here are short extracts to demonstrate
    Code:
    -------opXML--------
    <InvoiceLine>
        <LineNumber>1</LineNumber> 
        <InvoiceLineReferences /> 
        <Product>
            <SuppliersProductCode>XX-XX-XX</SuppliersProductCode> 
            <Description>nnnnnnnnnnnnnnnnn</Description> 
        </Product>
        <Quantity>
            <Amount>2</Amount> 
        </Quantity>
        <Price>
           <UnitPrice>35.5000</UnitPrice> 
           <LineTotalNet>71.00</LineTotalNet> 
           <LineTotalTax>12.43</LineTotalTax> 
           <LineTotal>83.43</LineTotal> 
        </Price>
        <LineTax /> 
    </InvoiceLine>
    Code:
    ------Bespoke---------
    <OrderLine>
        <LineNumber>1</LineNumber> 
        <Product>XXX-XXX</Product> 
        <Quantity>1</Quantity> 
        <Price>7.7900</Price> 
        <Personalised /> 
        <DiscValue /> 
        <LineTotalGross>7.79</LineTotalGross> 
        <LineTotalNet /> 
        <LineTotalTax /> 
    </OrderLine>
    As you can see, as well as different elements names the hierarchy is also different.

    I would like a generic function that could write either format depending on the function parameters.
    Passing this associtive array seems a good start
    Code:
    array(element name1=>value,
    element name2=>value,
    element name3=>value)
    But I cannot think of a way to pass the structure/hierarchy to match the elements.
    Any tips gratefully considered.
  • dgreenhouse
    Recognized Expert Contributor
    • May 2008
    • 250

    #2
    I've been toying with this concept for awhile myself. I haven't really spent the time to solve it yet, but I'll be working on something similar soon to emit valid xhtml fragments.

    It appears that there are never attributes on elements - only values. Is this always the case?

    Am I to assume that the difference in XML structure emitted is based on different fields drawn from queries? Is the acceptance of orders FROM a database or an external source? If from an external source – what's the input structure? Or are the orders from a front-end applicaton?

    Just curious ~ what are you using to generate the XML? XMLWriter, DOM, "Roll your own?"

    Also I'm curious about <InvoiceLineRef erences />... I assume this is part of the opXML (BOSS) standard (never worked with it), but I'm just wondering what that means in the standard? Is this like a self-join relationship between line items?

    Nice discussion start...!

    Comment

    • Dormilich
      Recognized Expert Expert
      • Aug 2008
      • 8694

      #3
      if you have an appropriately nested array, you could serialize that into a WDDX file and then transform that via XSLT into the desired XML format.

      Comment

      • code green
        Recognized Expert Top Contributor
        • Mar 2007
        • 1726

        #4
        dgreenhouse I've been toying with this concept for awhile myself
        So I am not alone
        It appears that there are never attributes on elements - only values. Is this always the case?
        Elements can have attributes AND values, or one of each or neither - just serving as a heading or so it seems.
        Is the acceptance of orders FROM a database or an external source? If from an external source – what's the input structure? Or are the orders from a front-end applicaton
        The original order format may be CSV (including the awful ebay format), XLS or Web-page. I manipulate them all into MySQL databases, and also download orders from a remote MySQL connection, then into the bespoke XML
        The opXML format originates from a MsSQL database so your asumption about different queries is correct.
        I am using DOM objects and write using these functions
        Code:
        //Returns a DOM object element level
        function createEntity(&$xml,&$thisLevel,$tag)
        {
        	if(!empty($tag))
        	{
           		$newtextnode = $xml->createTextNode(chr(10));
           		$thisLevel->appendChild($newtextnode);
        
        		$nextLevel = $xml->createElement($tag);
        		$thisLevel->appendChild($nextLevel);
        		return $nextLevel;
        	}
        	return false;
        }
        
        //Writes values into passed DOM object element level
        function writeText(&$xml,&$level,$text)
        {
        	$value = $xml->createTextNode(mb_convert_encoding
                (htmlspecialchars($text),'UTF-8'));
           	$level->appendChild($value);
        }
        I have no function for writing attributes yet..
        <InvoiceLineRef erences />... contains these elements in BOSS
        Code:
        <OrderLineNumber>1</OrderLineNumber> 
          <BuyersOrderLineReference>00001</BuyersOrderLineReference>

        Comment

        • dgreenhouse
          Recognized Expert Contributor
          • May 2008
          • 250

          #5
          code green,

          Sorry I haven't responded yet...

          I'm really interested in this subject and will ruminate on it over the next couple of days...

          Best...

          Comment

          • code green
            Recognized Expert Top Contributor
            • Mar 2007
            • 1726

            #6
            Dormilich if you have an appropriately nested array, you could serialize that
            Considered this, but to appropriately nest the array for each structure along with the differing elements would require a seperate function for each format. This is simply moving the structure creation to an earlier instance. Yes, I then can have a generic XMLcreate() but now have different structureCreate () functions for each format.

            What do you think about two arrays.
            One with key=>value, another with key=>parent.
            I am already creating this array dynamically
            Code:
            //Array for element name and values
            array(elementName1=>value1 , 
            elementName2=>value2, 
            elementName3=>value3)
            by array merging of some default values and a query result
            Code:
            SELECT value1 AS elementName1, 
            value2 AS elementName2, 
            value3 AS elementName3
            What about a hard coded array controlling the XML structure
            Code:
            //Array for element name and level
            array(elementName1=>parentNameX, 
            elementName2=>parentNameXX, 
            elementName3=>parentNameXX)
            Not sure how to fit any required attributes in there unfortunately

            Comment

            • kovik
              Recognized Expert Top Contributor
              • Jun 2007
              • 1044

              #7
              The only way to do this that comes to mind for me is to have one function that, depending on a boolean parameter, sends the information to the appropriate function for XML formatting. This way, you could manually define the nesting structure for either method.

              Comment

              • code green
                Recognized Expert Top Contributor
                • Mar 2007
                • 1726

                #8
                Or......I could store an XML template of each format, then prior to processing the orders, parse the required template into an array, which would give me the structure and element names.
                Then fill that array with values from my elementName=>va lue array
                by matching the element names.

                ...but I am not sure how to parse the structure from XML to the same array format

                Comment

                Working...