Discussion:
Unsetting of data objects using xpath not working as expected
cdouglas
2008-02-07 22:03:43 UTC
Permalink
Hello,
I am having an issue trying to remove a data object using xpath and
unset and its not working a I expect.

Example:
<record>
<tns:logicalPort id="lp24" parentId="mpg5" portId="24">
<tns:extendedData dataType="name" instance="1">LP 24</
tns:extendedData>
<tns:logicalPortLocation>LP 24</tns:logicalPortLocation>
</tns:logicalPort>
<tns:logicalPort id="lp25" parentId="mpg6" portId="25">
<tns:logicalPortLocation>Lp11222</tns:logicalPortLocation>
</tns:logicalPort>
</record>

I want to remove the entire object for <tns:logicalPort id="lp25"
parentId="mpg6" portId="25"> based on the portId.
So remove this:
<tns:logicalPort id="lp24" parentId="mpg5" portId="24">
<tns:extendedData dataType="name" instance="1">LP 24</
tns:extendedData>
<tns:logicalPortLocation>LP 24</tns:logicalPortLocation>
</tns:logicalPort>

The XML is loaded in to the object $record
If I execute unset($record["logicalPort[portId=24]"]) , nothing
happens.
But If I execute unset($record["logicalPort[portId=24]"]->parentId) ,
then the parentID value is removed, so I am not completely off base.
How can I remove the entire section?

Thanks
Chris
Caroline Maynard
2008-02-08 15:59:36 UTC
Permalink
Post by cdouglas
I am having an issue trying to remove a data object using xpath and
unset and it's not working as I expect.
<record>
<tns:logicalPort id="lp24" parentId="mpg5" portId="24">
<tns:extendedData dataType="name" instance="1">LP 24</
tns:extendedData>
<tns:logicalPortLocation>LP 24</tns:logicalPortLocation>
</tns:logicalPort>
<tns:logicalPort id="lp25" parentId="mpg6" portId="25">
<tns:logicalPortLocation>Lp11222</tns:logicalPortLocation>
</tns:logicalPort>
</record>
I want to remove the entire object for <tns:logicalPort id="lp25"
parentId="mpg6" portId="25"> based on the portId.
<tns:logicalPort id="lp24" parentId="mpg5" portId="24">
<tns:extendedData dataType="name" instance="1">LP 24</
tns:extendedData>
<tns:logicalPortLocation>LP 24</tns:logicalPortLocation>
</tns:logicalPort>
The XML is loaded in to the object $record
If I execute unset($record["logicalPort[portId=24]"]) , nothing
happens.
But If I execute unset($record["logicalPort[portId=24]"]->parentId) ,
then the parentID value is removed, so I am not completely off base.
How can I remove the entire section?
It's interesting that your second example shows that the xpath is
resolving correctly. What happens if you access the element more
directly, something like $record->logicalPort[0] - can you unset the
element that way?

If you could provide a minimal testcase, I'll run it in the debugger and
see what Tuscany is doing.
Caroline Maynard
2008-02-14 01:09:24 UTC
Permalink
Post by cdouglas
Hello,
I am having an issue trying to remove a data object using xpath and
unset and its not working a I expect.
<record>
<tns:logicalPort id="lp24" parentId="mpg5" portId="24">
<tns:extendedData dataType="name" instance="1">LP 24</
tns:extendedData>
<tns:logicalPortLocation>LP 24</tns:logicalPortLocation>
</tns:logicalPort>
<tns:logicalPort id="lp25" parentId="mpg6" portId="25">
<tns:logicalPortLocation>Lp11222</tns:logicalPortLocation>
</tns:logicalPort>
</record>
I want to remove the entire object for <tns:logicalPort id="lp25"
parentId="mpg6" portId="25"> based on the portId.
<tns:logicalPort id="lp24" parentId="mpg5" portId="24">
<tns:extendedData dataType="name" instance="1">LP 24</
tns:extendedData>
<tns:logicalPortLocation>LP 24</tns:logicalPortLocation>
</tns:logicalPort>
The XML is loaded in to the object $record
If I execute unset($record["logicalPort[portId=24]"]) , nothing
happens.
But If I execute unset($record["logicalPort[portId=24]"]->parentId) ,
then the parentID value is removed, so I am not completely off base.
How can I remove the entire section?
Well, I'm not happy with the answer. It is working as designed, but this
does imply that the design is somewhat flawed.

The xpath support was only specified to work with instances of
SDO_DataObject. But $record->logicalPort is not an SDO_DataObject, it is
an instance of SDO_List.

The problem is apparent if you try to access a list element using an
xpath. For example
$do = $record->logicalPort['portId=24'];
results in the oh-so-explanatory message:
PHP Fatal error: main(): internal error (747) - invalid dimension
type 6 in <source> on line <nn>

In other words, you are using a String (type==6) as an index into a
list, but only Integers are valid. There's clearly a check missing
somewhere, because when you do your unset, it just silently fails and
doesn't present an error message.

I'm not hopeful that Tuscany would want to add the function to access a
list element using xpath, though I could ask.

In the PHP implementation, we could at least fix both the baffling error
message and the failure to output an error message when you attempt to
unset a list element using xpath, though.

As discussed, your best bet for now is to iterate through the list to
find the index of the element you want to remove. Then unset it using
the index as a numeric index. HTH
Caroline Maynard
2008-02-14 01:09:52 UTC
Permalink
Post by cdouglas
Hello,
I am having an issue trying to remove a data object using xpath and
unset and its not working a I expect.
<record>
<tns:logicalPort id="lp24" parentId="mpg5" portId="24">
<tns:extendedData dataType="name" instance="1">LP 24</
tns:extendedData>
<tns:logicalPortLocation>LP 24</tns:logicalPortLocation>
</tns:logicalPort>
<tns:logicalPort id="lp25" parentId="mpg6" portId="25">
<tns:logicalPortLocation>Lp11222</tns:logicalPortLocation>
</tns:logicalPort>
</record>
I want to remove the entire object for <tns:logicalPort id="lp25"
parentId="mpg6" portId="25"> based on the portId.
<tns:logicalPort id="lp24" parentId="mpg5" portId="24">
<tns:extendedData dataType="name" instance="1">LP 24</
tns:extendedData>
<tns:logicalPortLocation>LP 24</tns:logicalPortLocation>
</tns:logicalPort>
The XML is loaded in to the object $record
If I execute unset($record["logicalPort[portId=24]"]) , nothing
happens.
But If I execute unset($record["logicalPort[portId=24]"]->parentId) ,
then the parentID value is removed, so I am not completely off base.
How can I remove the entire section?
Well, I'm not happy with the answer. It is working as designed, but this
does imply that the design is somewhat flawed.

The xpath support was only specified to work with instances of
SDO_DataObject. But $record->logicalPort is not an SDO_DataObject, it is
an instance of SDO_List.

The problem is apparent if you try to access a list element using an
xpath. For example
$do = $record->logicalPort['portId=24'];
results in the oh-so-explanatory message:
PHP Fatal error: main(): internal error (747) - invalid dimension
type 6 in <source> on line <nn>

In other words, you are using a String (type==6) as an index into a
list, but only Integers are valid. There's clearly a check missing
somewhere, because when you do your unset, it just silently fails and
doesn't present an error message.

I'm not hopeful that Tuscany would want to add the function to access a
list element using xpath, though I could ask.

In the PHP implementation, we could at least fix both the baffling error
message and the failure to output an error message when you attempt to
unset a list element using xpath, though.

As discussed, your best bet for now is to iterate through the list to
find the index of the element you want to remove. Then unset it using
the index as a numeric index. HTH
cdouglas
2008-02-22 13:55:45 UTC
Permalink
Thank you for checking into it for me. I guess I'll loop through the
results and remove when I find a match.

Loading...