XML Text Node with an Attribute

Login or register to post comments
10 replies [Last post]
Offline
Joined: 06/25/2009

I'm working on taking some PHP classes and serializing them into XML. Rather than using arrays, I'm just using classes with public properties named the same as the XML nodes. This is working perfectly until I get to a XML text node that has an attribute attached to it. Here's an example:

<Money currency="USD">40.0</Money>

Here's what my generated class looks like in my .NET simulator:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = true)]
public partial class Money
{

    private string currencyField;

    private string valueField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string currency
    {
        get
        {
            return this.currencyField;
        }
        set
        {
            this.currencyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value
    {
        get
        {
            return this.valueField;
        }
        set
        {
            this.valueField = value;
        }
    }
}

Here's what my PHP class looks like:

class Money
{
public $Value;
public $currency;
public function __construct($value, $currency)
{
$this->Value = $value;
$this->currency = $currency;
}
}

The value of currency comes through, but the actual value of Money does not. Anyone know how to do this? Changing XML schema's is not an option since it's set by our client.

Thanks.

alex94040's picture
Offline
Joined: 11/06/2008

I'm really confused about what you're trying to do. How is the .NET code relevant?

Are you just trying to serialize PHP objects into XML?

Offline
Joined: 06/25/2009

The .NET code is from my test app that I'm using to simulate the web service end point. That's how the Money class was generated by .NET, I just wanted to give as much info as possible, but maybe I made it too confusing by doing so. :)

I'm trying to serialize my PHP object into XML, and up until I have a XML node such as the one above, it works beautifully. For everything else that is either a XML element OR attribute, my class structure works, but the issue is when I have a node with BOTH an attribute AND a text value, such as the Money node above. I'm not sure how to represent that with my PHP class or with an array.

alex94040's picture
Offline
Joined: 11/06/2008

I'm still seriously confused.

If you have a money class like this:

class Money
{
public $value;
public $currency;
}

you can just write a method inside the money class that converts it to XML:

public function toXml() {
  $xml = '<money currency="' . $this->currency . '">' . $this->value . "</money>";

  return $xml;
}

And just call that function whenever you want to serialize a Money object?

Offline
Joined: 06/25/2009

Here's a scaled down sample of code that I put together for this:

$strWsdlUrl = "http://localhost/WebService.asmx?WSDL";
$client = new SoapClient($strWsdlUrl);

$MoneyTest = array('Money' => new Money('40.00', 'USD'));
$AlexMoneyTest = array('Money' => '<Money currency="USD">40.00</Money>');
$client->MoneyTest($MoneyTest);

class Money
{
public $Value;
public $currency;
public function __construct($value, $currency)
{
$this->Value = $value;
$this->currency = $currency;
}
public function toXml()
{
  $xml = '<Money currency="' . $this->currency . '">' . $this->value . "</Money>";

  return $xml;
}
}

When I give the web service the $MoneyTest array, only the currency is coming through. When I give it the $AlexMoneyTest array, the entire node appears as the text value, and nothing in the currency slot.

Thanks for looking at this, I appreciate it.

alex94040's picture
Offline
Joined: 11/06/2008

It looks like the problem is in the web service, not in the XML serialization of your object. What I'd recommend is to create a sample XML file that you want to send up to the cloud; then get one of the SOAP client testing tools (like http://www.soapui.org/ or something like that) and send up this exact XML. Do not involve PHP at all. See what the server will return.

Offline
Joined: 06/25/2009

I don't believe this issue is with the web service. Here's the SOAP from soapUI or WSStudio(another web service tester):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.myapp.com/">
<soapenv:Header />
<soapenv:Body>
<ws:MoneyTest>
<!--Optional:-->
<ws:Money currency="USD">40.0</ws:Money>
</ws:MoneyTest>
</soapenv:Body>
</soapenv:Envelope>

Here's the SOAP that PHP generates:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://ws.myapp.com/">
<SOAP-ENV:Body>
<ns1:MoneyTest>
<ns1:Money currency="USD" />
</ns1:MoneyTest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Offline
Joined: 06/25/2009

I figured it out! For any node like this, the property should be represented as just a '_' for either the array, or a class property. Here's my PHP Money class now:

class Money
{
public $_;
public $currency;
public function __construct($value, $currency)
{
$this->_ = $value;
$this->currency = $currency;
}
}

Easton's picture
Offline
Joined: 02/24/2010

(Maybe this issue may shift to other section.)

My plan is to build xml objects within the qcubed framework. I watched the last post from ShannyMan and I think, before I use to switch to soap I'd like to use REST interface for my applications.

Steps to do:
1. generate objects from sybasq db (sql statements)
2. take 1 or more generated Objects and transform it into XML objects
3. Save these objects onto filesystem folder.

1st Question: where in the framework may I find the specific definitions for DB Types?

2nd Question: Are they any xml methods or functions in the framework api?

3rd Question: How do I create my own QMethods? Are there any samples to learn from?

thx,
Easton