You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@royale.apache.org by Harbs <ha...@gmail.com> on 2021/11/11 09:39:32 UTC

null values in XML

At some point (not sure when), it seems like when writing xml, empty string attributes became “null” instead of “”.

Any ideas when/how that happened?

Re: null values in XML

Posted by Harbs <ha...@gmail.com>.
Looking into it.

I suspect it might be caused by copy().

Yup. I just stepped through copy()

data.toXMLString() is correct.

<foo baz="”/>

after:
this._rawXML = data.copy();

<foo baz="null”/>

I wonder if Language.string() should return “” for undefined.

Thoughts?

> On Nov 12, 2021, at 9:14 AM, Edward Stangler <es...@bradmark.com> wrote:
> 
> 
> How are you creating the XML object and converting it back to a string,
> exactly?
> 
> I just tested doing this:
> 
>   var x:XML = new XML("<foo baz=\"\"><bar /></foo>");
>   l.text = "XML = " + x.toString();
> 
> And it works fine.  (But note that <foo baz=""/> makes x.toString() ==
> "", because root tag <foo> doesn't have a child.)
> 
> Doing "<myxml><foo baz=\"\"/></myxml>" also works fine.
> 
> 
> On 11/11/2021 10:31 AM, Harbs wrote:
>> I have XML which had <foo baz=“”/> and after reading it into an XML object and writing it back I get <foo baz=“null”/>
>> 
>> I have not yet investigated at which point it becomes “null”. 
>> 
>>> On Nov 11, 2021, at 5:11 PM, Edward Stangler <es...@bradmark.com> wrote:
>>> 
>>> 
>>> In what context?  Like an example.
>>> 
>>> 
>>> On 11/11/2021 3:40 AM, Harbs wrote:
>>>> At some point (not sure when), it seems like when writing xml, empty string attributes became “null” instead of “”.
>>>> 
>>>> Any ideas when/how that happened?
>>> 
>> 
> 


Re: null values in XML

Posted by Harbs <ha...@gmail.com>.
Because empty strings use memory.

> On Nov 12, 2021, at 8:19 PM, Edward Stangler <es...@bradmark.com> wrote:
> 
> 
> Why is XML.copy() not setting ""?
> 
> 
> On 11/12/2021 4:05 AM, Harbs wrote:
>> xml.toXMLString() is correct.
>> 
>> <foo baz="”/>
>> 
>> after:
>> xml2 = data.copy();
>> 
>> <foo baz="null”/>
>> 
>> I believe there’s two problems:
>> 
>> 1. XML.toString() blindly returns _value for attributes even though they can be undefined. Leaving them undefined saves memory.
>> 2. XML.escapeAttributeValue uses String(value) which can result in “undefined”.
>> 
> 


Re: null values in XML

Posted by Edward Stangler <es...@bradmark.com>.
Why is XML.copy() not setting ""?


On 11/12/2021 4:05 AM, Harbs wrote:
> xml.toXMLString() is correct.
>
> <foo baz="”/>
>
> after:
> xml2 = data.copy();
>
> <foo baz="null”/>
>
> I believe there’s two problems:
>
> 1. XML.toString() blindly returns _value for attributes even though they can be undefined. Leaving them undefined saves memory.
> 2. XML.escapeAttributeValue uses String(value) which can result in “undefined”.
>


Re: Language.string behavior (was Re: null values in XML)

Posted by Edward Stangler <es...@bradmark.com>.
What I'm getting at:  maybe it should return "null" instead of null.


On 11/13/2021 1:24 PM, Harbs wrote:
> Of course and JS works the same way. But Language.string is used for implicit coercions where it might have an initial value of undefined. In that case, I don’t think you’d usually want to be using “undefined”. You probably want “” instead.
>
> I don’t remember all the discussions we had around this in the past.
>
> If anyone remembers better, please jog my memory…
>
> Harbs
>
>> On Nov 12, 2021, at 8:08 PM, Edward Stangler wrote:
>>
>>
>> In Flex, both String(null) == "null" and ""+null == "null" (the string
>> "null", not the null value).
>>
>> Don't know if that's the equivalent of Language.string().
>>
>>
>> On 11/12/2021 4:05 AM, Harbs wrote:
>>> I wonder if Language.string() should return “” for undefined. It currently returns null. I think “” would generally be a more expected result.
>


Re: Language.string behavior (was Re: null values in XML)

Posted by Harbs <ha...@gmail.com>.
Fair enough.

I guess we should examine how it’s being used. In my app I found 612 cases of Language.string being used.

I should go though them and catalog when it’s being used.

One that jumped out at me is:

var qString:String = qualifiers.toXMLString();

compiles to:

var /** @type {string} */ qString = org.apache.royale.utils.Language.string(qualifiers.toXMLString());

qualifiers is of type XML and toXMLString() returns a string.

It looks like almost every case of XML.toXMLString() is being wrapped in Language.string. That seems like a bug.

> On Nov 14, 2021, at 1:15 AM, Edward Stangler <es...@bradmark.com> wrote:
> 
> 
> I think you're right.  According to the AVM2 doc (avm2overview.pdf), for
> coerce_s ("Coerce a value to a string"):
> 
> "If value is null or undefined, then stringvalue is set to null"
> 
> and
> 
> "This opcode is very similar to the convert_s opcode. The difference is
> that convert_s will convert a null or undefined value to the string
> "null" or "undefined" whereas coerce_s will convert those values to the
> null value."
> 
> 
> 
> On 11/13/2021 3:49 PM, Greg Dove wrote:
>> I am pretty sure Language.string is behaving correctly.
>> 
>> Here's a very simple example of what you get in flash player.
>> 
>> var something:* //undefined by default
>> 
>> var str1:String = something;
>> var str2:String = something as String;
>> var str3:String = String(something);
>> 
>> trace((str1===null),(str2===null),(str3==='undefined'))
>> //true true true
>> 
>> here is what the same code compiles to in Royale:
>> 
>>  var /** @type {*} */ something;
>>  var /** @type {string} */ str1 =
>> org.apache.royale.utils.Language.string(something);
>>  var /** @type {string} */ str2 =
>> org.apache.royale.utils.Language.as(something,
>> String);
>>  var /** @type {string} */ str3 = String(something);
>> 
>> And the results, when tested, are the same. Whether or not 'something as
>> String' should be transpiled to Language.string instead of Language.as is
>> 'something' that could perhaps be investigated, but I suspect the explicit
>> use of that is quite rare in code, relative to the implicit coercions that
>> take place.
>> 
>> 
>> 
>> 
>> On Sun, Nov 14, 2021 at 8:23 AM Harbs wrote:
>> 
>>> Of course and JS works the same way. But Language.string is used for
>>> implicit coercions where it might have an initial value of undefined. In
>>> that case, I don’t think you’d usually want to be using “undefined”. You
>>> probably want “” instead.
>>> 
>>> I don’t remember all the discussions we had around this in the past.
>>> 
>>> If anyone remembers better, please jog my memory…
>>> 
>>> Harbs
>>> 
>>>> On Nov 12, 2021, at 8:08 PM, Edward Stangler 
>>> wrote:
>>>> 
>>>> In Flex, both String(null) == "null" and ""+null == "null" (the string
>>>> "null", not the null value).
>>>> 
>>>> Don't know if that's the equivalent of Language.string().
>>>> 
>>>> 
>>>> On 11/12/2021 4:05 AM, Harbs wrote:
>>>>> I wonder if Language.string() should return “” for undefined. It
>>> currently returns null. I think “” would generally be a more expected
>>> result.


Re: Language.string behavior (was Re: null values in XML)

Posted by Edward Stangler <es...@bradmark.com>.
I think you're right.  According to the AVM2 doc (avm2overview.pdf), for
coerce_s ("Coerce a value to a string"):

"If value is null or undefined, then stringvalue is set to null"

and

"This opcode is very similar to the convert_s opcode. The difference is
that convert_s will convert a null or undefined value to the string
"null" or "undefined" whereas coerce_s will convert those values to the
null value."



On 11/13/2021 3:49 PM, Greg Dove wrote:
> I am pretty sure Language.string is behaving correctly.
>
> Here's a very simple example of what you get in flash player.
>
> var something:* //undefined by default
>
> var str1:String = something;
> var str2:String = something as String;
> var str3:String = String(something);
>
> trace((str1===null),(str2===null),(str3==='undefined'))
> //true true true
>
> here is what the same code compiles to in Royale:
>
>   var /** @type {*} */ something;
>   var /** @type {string} */ str1 =
> org.apache.royale.utils.Language.string(something);
>   var /** @type {string} */ str2 =
> org.apache.royale.utils.Language.as(something,
> String);
>   var /** @type {string} */ str3 = String(something);
>
> And the results, when tested, are the same. Whether or not 'something as
> String' should be transpiled to Language.string instead of Language.as is
> 'something' that could perhaps be investigated, but I suspect the explicit
> use of that is quite rare in code, relative to the implicit coercions that
> take place.
>
>
>
>
> On Sun, Nov 14, 2021 at 8:23 AM Harbs wrote:
>
>> Of course and JS works the same way. But Language.string is used for
>> implicit coercions where it might have an initial value of undefined. In
>> that case, I don’t think you’d usually want to be using “undefined”. You
>> probably want “” instead.
>>
>> I don’t remember all the discussions we had around this in the past.
>>
>> If anyone remembers better, please jog my memory…
>>
>> Harbs
>>
>>> On Nov 12, 2021, at 8:08 PM, Edward Stangler 
>> wrote:
>>>
>>> In Flex, both String(null) == "null" and ""+null == "null" (the string
>>> "null", not the null value).
>>>
>>> Don't know if that's the equivalent of Language.string().
>>>
>>>
>>> On 11/12/2021 4:05 AM, Harbs wrote:
>>>> I wonder if Language.string() should return “” for undefined. It
>> currently returns null. I think “” would generally be a more expected
>> result.
>>


Re: Language.string behavior (was Re: null values in XML)

Posted by Greg Dove <gr...@gmail.com>.
I am pretty sure Language.string is behaving correctly.

Here's a very simple example of what you get in flash player.

var something:* //undefined by default

var str1:String = something;
var str2:String = something as String;
var str3:String = String(something);

trace((str1===null),(str2===null),(str3==='undefined'))
//true true true

here is what the same code compiles to in Royale:

  var /** @type {*} */ something;
  var /** @type {string} */ str1 =
org.apache.royale.utils.Language.string(something);
  var /** @type {string} */ str2 =
org.apache.royale.utils.Language.as(something,
String);
  var /** @type {string} */ str3 = String(something);

And the results, when tested, are the same. Whether or not 'something as
String' should be transpiled to Language.string instead of Language.as is
'something' that could perhaps be investigated, but I suspect the explicit
use of that is quite rare in code, relative to the implicit coercions that
take place.




On Sun, Nov 14, 2021 at 8:23 AM Harbs <ha...@gmail.com> wrote:

> Of course and JS works the same way. But Language.string is used for
> implicit coercions where it might have an initial value of undefined. In
> that case, I don’t think you’d usually want to be using “undefined”. You
> probably want “” instead.
>
> I don’t remember all the discussions we had around this in the past.
>
> If anyone remembers better, please jog my memory…
>
> Harbs
>
> > On Nov 12, 2021, at 8:08 PM, Edward Stangler <es...@bradmark.com>
> wrote:
> >
> >
> > In Flex, both String(null) == "null" and ""+null == "null" (the string
> > "null", not the null value).
> >
> > Don't know if that's the equivalent of Language.string().
> >
> >
> > On 11/12/2021 4:05 AM, Harbs wrote:
> >> I wonder if Language.string() should return “” for undefined. It
> currently returns null. I think “” would generally be a more expected
> result.
> >
>
>

Language.string behavior (was Re: null values in XML)

Posted by Harbs <ha...@gmail.com>.
Of course and JS works the same way. But Language.string is used for implicit coercions where it might have an initial value of undefined. In that case, I don’t think you’d usually want to be using “undefined”. You probably want “” instead.

I don’t remember all the discussions we had around this in the past.

If anyone remembers better, please jog my memory…

Harbs

> On Nov 12, 2021, at 8:08 PM, Edward Stangler <es...@bradmark.com> wrote:
> 
> 
> In Flex, both String(null) == "null" and ""+null == "null" (the string
> "null", not the null value).
> 
> Don't know if that's the equivalent of Language.string().
> 
> 
> On 11/12/2021 4:05 AM, Harbs wrote:
>> I wonder if Language.string() should return “” for undefined. It currently returns null. I think “” would generally be a more expected result.
> 


Re: null values in XML

Posted by Edward Stangler <es...@bradmark.com>.
In Flex, both String(null) == "null" and ""+null == "null" (the string
"null", not the null value).

Don't know if that's the equivalent of Language.string().


On 11/12/2021 4:05 AM, Harbs wrote:
> I wonder if Language.string() should return “” for undefined. It currently returns null. I think “” would generally be a more expected result.


Re: null values in XML

Posted by Harbs <ha...@gmail.com>.
Yes. It was supposed to be doing that, but some cases were missed.

The change I made was necessary to properly return empty strings.

I just made a new commit which does a better job of handling and preserving the undefined values.

I also fixed an issue with setting null and undefined which was not handled the same way as Flash. I added tests for that too.

Harbs

> On Nov 13, 2021, at 2:18 AM, Edward Stangler <es...@bradmark.com> wrote:
> 
> If there is a change to save space (i.e. _value == "" => _value = null),
> then I think it would be better done elsewhere and more holistically,
> rather than having original XML vs. XML.copy() behave differently.  At
> least, it makes it harder to code and test for both cases.


Re: null values in XML

Posted by Edward Stangler <es...@bradmark.com>.
I made PR #1164, to revert a change you made back in December 2019 that
prevented copying the blank value.  It fixes the issue in my testing.

If there is a change to save space (i.e. _value == "" => _value = null),
then I think it would be better done elsewhere and more holistically,
rather than having original XML vs. XML.copy() behave differently.  At
least, it makes it harder to code and test for both cases.

Perhaps someone could add a test for this case, if there isn't one already.


On 11/12/2021 12:19 PM, Edward Stangler wrote:
>
> Why is XML.copy() not setting ""?
>
>
> On 11/12/2021 4:05 AM, Harbs wrote:
>> xml.toXMLString() is correct.
>>
>> <foo baz="”/>
>>
>> after:
>> xml2 = data.copy();
>>
>> <foo baz="null”/>
>>
>> I believe there’s two problems:
>>
>> 1. XML.toString() blindly returns _value for attributes even though
>> they can be undefined. Leaving them undefined saves memory.
>> 2. XML.escapeAttributeValue uses String(value) which can result in
>> “undefined”.
>>
>
>


Re: null values in XML

Posted by Harbs <ha...@gmail.com>.
Looking into it.

I suspect it might be caused by copy().

Yup. I just stepped through copy()

Sample project:

<?xml version="1.0" encoding="utf-8"?>
<js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                xmlns:js="library://ns.apache.org/royale/basic"
                applicationComplete="onComplete()">
    <fx:Script>
        <![CDATA[
            private function onComplete():void{
                var xml:XML = <foo baz=""/>;
                trace(xml.toXMLString());
                var xml2:XML = xml.copy();
                trace(xml2.toXMLString());
            }
        ]]>
    </fx:Script>
    <js:valuesImpl>
        <js:SimpleCSSValuesImpl />
    </js:valuesImpl>
    <js:initialView>
    <js:View>
    <js:Label text="Hi!"/>
    </js:View>
    </js:initialView>
</js:Application>

xml.toXMLString() is correct.

<foo baz="”/>

after:
xml2 = data.copy();

<foo baz="null”/>

I believe there’s two problems:

1. XML.toString() blindly returns _value for attributes even though they can be undefined. Leaving them undefined saves memory.
2. XML.escapeAttributeValue uses String(value) which can result in “undefined”.

Both issues can be fixed in XML, but it’s an indication of a wider problem IMO.
I wonder if Language.string() should return “” for undefined. It currently returns null. I think “” would generally be a more expected result.

Thoughts?

> On Nov 12, 2021, at 9:14 AM, Edward Stangler <es...@bradmark.com> wrote:
> 
> 
> How are you creating the XML object and converting it back to a string,
> exactly?
> 
> I just tested doing this:
> 
>  var x:XML = new XML("<foo baz=\"\"><bar /></foo>");
>  l.text = "XML = " + x.toString();
> 
> And it works fine.  (But note that <foo baz=""/> makes x.toString() ==
> "", because root tag <foo> doesn't have a child.)
> 
> Doing "<myxml><foo baz=\"\"/></myxml>" also works fine.
> 
> 
> On 11/11/2021 10:31 AM, Harbs wrote:
>> I have XML which had <foo baz=“”/> and after reading it into an XML object and writing it back I get <foo baz=“null”/>
>> 
>> I have not yet investigated at which point it becomes “null”. 
>> 
>>> On Nov 11, 2021, at 5:11 PM, Edward Stangler <es...@bradmark.com> wrote:
>>> 
>>> 
>>> In what context?  Like an example.
>>> 
>>> 
>>> On 11/11/2021 3:40 AM, Harbs wrote:
>>>> At some point (not sure when), it seems like when writing xml, empty string attributes became “null” instead of “”.
>>>> 
>>>> Any ideas when/how that happened?
>>> 
>> 
> 


Re: null values in XML

Posted by Edward Stangler <es...@bradmark.com>.
How are you creating the XML object and converting it back to a string,
exactly?

I just tested doing this:

    var x:XML = new XML("<foo baz=\"\"><bar /></foo>");
    l.text = "XML = " + x.toString();

And it works fine.  (But note that <foo baz=""/> makes x.toString() ==
"", because root tag <foo> doesn't have a child.)

Doing "<myxml><foo baz=\"\"/></myxml>" also works fine.


On 11/11/2021 10:31 AM, Harbs wrote:
> I have XML which had <foo baz=“”/> and after reading it into an XML object and writing it back I get <foo baz=“null”/>
>
> I have not yet investigated at which point it becomes “null”. 
>
>> On Nov 11, 2021, at 5:11 PM, Edward Stangler <es...@bradmark.com> wrote:
>>
>>
>> In what context?  Like an example.
>>
>>
>> On 11/11/2021 3:40 AM, Harbs wrote:
>>> At some point (not sure when), it seems like when writing xml, empty string attributes became “null” instead of “”.
>>>
>>> Any ideas when/how that happened?
>>
>


Re: null values in XML

Posted by Harbs <ha...@gmail.com>.
It’s very possible that it’s more complicated than I say… ;-)

We can discuss the details off-list of my particular problem.

> On Nov 11, 2021, at 9:12 PM, Greg Dove <gr...@gmail.com> wrote:
> 
> Not sure how or when that happened, but I will have time to look into it
> and figure it out tomorrow. I am surprised it is not already captured in
> some of the tests, but will add one in to make sure we cover that off.
> 
> 
> On Fri, Nov 12, 2021 at 5:29 AM Harbs <ha...@gmail.com> wrote:
> 
>> I have XML which had <foo baz=“”/> and after reading it into an XML object
>> and writing it back I get <foo baz=“null”/>
>> 
>> I have not yet investigated at which point it becomes “null”.
>> 
>>> On Nov 11, 2021, at 5:11 PM, Edward Stangler <es...@bradmark.com>
>> wrote:
>>> 
>>> 
>>> In what context?  Like an example.
>>> 
>>> 
>>> On 11/11/2021 3:40 AM, Harbs wrote:
>>>> At some point (not sure when), it seems like when writing xml, empty
>> string attributes became “null” instead of “”.
>>>> 
>>>> Any ideas when/how that happened?
>>> 
>>> 
>> 
>> 


Re: null values in XML

Posted by Greg Dove <gr...@gmail.com>.
Not sure how or when that happened, but I will have time to look into it
and figure it out tomorrow. I am surprised it is not already captured in
some of the tests, but will add one in to make sure we cover that off.


On Fri, Nov 12, 2021 at 5:29 AM Harbs <ha...@gmail.com> wrote:

> I have XML which had <foo baz=“”/> and after reading it into an XML object
> and writing it back I get <foo baz=“null”/>
>
> I have not yet investigated at which point it becomes “null”.
>
> > On Nov 11, 2021, at 5:11 PM, Edward Stangler <es...@bradmark.com>
> wrote:
> >
> >
> > In what context?  Like an example.
> >
> >
> > On 11/11/2021 3:40 AM, Harbs wrote:
> >> At some point (not sure when), it seems like when writing xml, empty
> string attributes became “null” instead of “”.
> >>
> >> Any ideas when/how that happened?
> >
> >
>
>

Re: null values in XML

Posted by Harbs <ha...@gmail.com>.
I have XML which had <foo baz=“”/> and after reading it into an XML object and writing it back I get <foo baz=“null”/>

I have not yet investigated at which point it becomes “null”. 

> On Nov 11, 2021, at 5:11 PM, Edward Stangler <es...@bradmark.com> wrote:
> 
> 
> In what context?  Like an example.
> 
> 
> On 11/11/2021 3:40 AM, Harbs wrote:
>> At some point (not sure when), it seems like when writing xml, empty string attributes became “null” instead of “”.
>> 
>> Any ideas when/how that happened?
> 
> 


Re: null values in XML

Posted by Edward Stangler <es...@bradmark.com>.
In what context?  Like an example.


On 11/11/2021 3:40 AM, Harbs wrote:
> At some point (not sure when), it seems like when writing xml, empty string attributes became “null” instead of “”.
>
> Any ideas when/how that happened?