Is it possible for XSD to apply (bitwise) logic between two XML attributes?
I hope to catch the following schema violation:
<parent mask="0x0007">
<child id="1" value="0x0001"/>
<child id="2" value="0x0002"/>
<child id="x" value="0x0010"/> // catch this!
</parent>
child x can clearly not be masked by its parent.
In simple logic:
if ((value AND mask) != value) then
# child element is invalid
endif
My application can of course catch this during the loading of the XML.
But my application applies schema validation prior to that and it would be grand if we can catch this during that stage.
Related
Given a list of objects that contains an ID and an ELEMENT, I need to iterate over the list and produce XML that looks like this:
<object id="1">
<element>...</element>
<object id="2">
<element>...</element>
<object id="3">
<element>...</element>
</object>
</object>
</object>
Note each object is created WITHIN the previous object, and objects are only closed off at the end of the list. (Not my choice, dictated by an external interface)
Is there a way to produce this using the XML Markup Builder?
class MyElement {
def id
def element
}
def list = [new MyElement(id: 1, element: "element1"),
new MyElement(id: 2, element: "element2"),
new MyElement(id: 3, element: "element3")]
println new groovy.xml.StreamingMarkupBuilder().bind {
def foo // note declaration and initialization on different lines
foo = { List<MyElement> l ->
if (l.isEmpty()) return
def head = l.head()
def tail = l.tail()
object {
id head.id
element head.element
foo(tail)
}
}
foo(list)
}
Output (prettified):
<object>
<id>1</id>
<element>element1</element>
<object>
<id>2</id>
<element>element2</element>
<object>
<id>3</id>
<element>element3</element>
</object>
</object>
</object>`
Hi I am trying to fetch the accounts from CRM 2011. I am fetching the data in the EntityCollection . But when I am trying to read or access data from entityCollection it displayed first record but throwing an error after that record. Kindly have a look to below code and suggest me.
string fetch2 = #"
<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='account'>
<attribute name='name' />
<attribute name='address1_city' />
<attribute name='primarycontactid' />
<attribute name='telephone1' />
<attribute name='accountid' />
<order attribute='name' descending='false' />
<filter type='and'>
<condition attribute='accounttype' operator='eq' value='01' />
</filter>
</entity>
</fetch>";
try
{
EntityCollection fxResult = _service.RetrieveMultiple(new FetchExpression(fetch2));
foreach (var e in fxResult.Entities)
{
Console.WriteLine("Id:{0},Name:{1},City:{2}", e.Attributes ["accountid"].ToString(), e.Attributes["name"].ToString(), e.Attributes["address1_city"].ToString());
// Console.WriteLine("Id:{0},Name:{1},City:{2}", e.ToEntity["accountid"]);
}
}
catch (Exception e)
{
Console.WriteLine("Error:==" + e.Message);
}
Before access an attribute you need to ask if it is in the context:
e.Attributes.Contains("address1_city")
If the collection contains the attribute, then you can access it safe.
string accountid = (string)e.Attributes["address1_city"]
The reason the attribute doesn't come in the collection it's because it is null or you are not retrieving it. In this case maybe, one of your attributes is null. Maybe address1_city.
When retrieving attribute values of late-bound Entity objects, the recommended approach is to use method getAttributeValue<T>. When the attribute is not present in the entity's attribute collection, it returns default(T).
The primary key ('id') of the record is always present when it is returned by the OrganizationService.
So your code should look like this:
EntityCollection fxResult = _service.RetrieveMultiple(new FetchExpression(fetch2));
foreach (var e in fxResult.Entities)
{
Console.WriteLine(
"Id:{0},Name:{1},City:{2}",
e.Id,
e.GetAttributeValue<string>("name"),
e.GetAttributeValue<string>("address1_city"));
}
You can safely use the item selector when you need to assign a value to an attribute, regardless if it is already present or not.
E.g. the following code line is valid:
e["name"] = "Demo Accountname";
I need to set Ship Date to current date, when I'm trying to confirm shipment. But I don't know where it to set. In documentation example don't have this attribute.
My XML code:
<?xml version="1.0" encoding="UTF-8"?>
<AmazonEnvelope xsi:noNamespaceSchemaLocation="amzn-envelope.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<DocumentVersion>1.02</DocumentVersion>
<MerchantIdentifier>XXXXXXXXXXXX</MerchantIdentifier>
</Header>
<MessageType>OrderFulfillment</MessageType>
<Message>
<MessageID>1</MessageID>
<OperationType>Update</OperationType>
<OrderFulfillment>
<AmazonOrderID>103-8280673-5282661</AmazonOrderID>
<FulfillmentDate>2015-01-22T06:30:00</FulfillmentDate>
<FulfillmentData>
<CarrierName>USPS</CarrierName>
<ShipperTrackingNumber>1234567890</ShipperTrackingNumber>
</FulfillmentData>
<Item>
<AmazonOrderItemCode>18531427322146</AmazonOrderItemCode>
<Quantity>1</Quantity>
</Item>
<Item>
<AmazonOrderItemCode>54419133385610</AmazonOrderItemCode>
<Quantity>1</Quantity>
</Item>
</OrderFulfillment>
</Message>
</AmazonEnvelope>
I'm trying to set Ship Date into <OrderFulfillment>, <FulfillmentData> - no result.
I'm trying to write it like <ShipDate>, <ShippingDate>, <ShippedDate> - no result.
Error returned:
<Result>
<MessageID>1</MessageID>
<ResultCode>Error</ResultCode>
<ResultMessageCode>25</ResultMessageCode>
<ResultDescription>We are unable to process the XML feed because one or more items are invalid. Please re-submit the feed.</ResultDescription>
</Result>
Maybe someone knows how to set Ship Date?
The above should fix it. And also, FulfillmentDate can also be the following format:
<FulfillmentDate>2015-01-22T06:30:00Z</FulfillmentDate>
And remove this tag:
<OperationType>Update</OperationType>
I am using same XML feed but without <OperationType>Update</OperationType>
and <item> tag because you don't need tag if you are shipping whole order.
and then I am doing following PHP code
$feed = trim($feed);
$marketplaceIdArray = array("Id" => array($MARKETPLACE_ID));
$feedHandle = #fopen('php://temp', 'rw+');
fwrite($feedHandle, $feed);
rewind($feedHandle); //Sets file pointer at beginning of file
$parameters = array(
'Merchant' => $MERCHANT_ID,
'MarketplaceIdList' => $marketplaceIdArray,
'FeedType' => '_POST_ORDER_FULFILLMENT_DATA_',
'FeedContent' => $feedHandle,
'PurgeAndReplace' => false, //Leave this PurgeAndReplace to false so that it want replace whole product in amazon inventory
'ContentMd5' => base64_encode(md5(stream_get_contents($feedHandle), true))
);
rewind($feedHandle);
$request = new MarketplaceWebService_Model_SubmitFeedRequest($parameters);
Not entirely positive on this but something that our feed contains is
<FulfillmentDate>2015-01-22T06:30:00+00:00</FulfillmentDate>
Instead of
<FulfillmentDate>2015-01-22T06:30:00</FulfillmentDate>
And that's the only thing that is not exactly the same as ours.
EDIT 1: I lied, there is a tag you have that I do not.
<OperationType>Update</OperationType>
I wonder if I can get the parameters and/or properties of an xpage or custom control programmatically.
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" id="layout">
<xp:this.properties>
<xp:parameter name="testcc.xsp" value="Test 1"></xp:parameter>
<xp:parameter name="index.xsp" value="Main"></xp:parameter>
</xp:this.properties>
...
How can I access this parameter list to use it e.g. in a repeat control?
EDIT
You both are right, thank you! But this works only on a page, not in a custom control.
EDIT
You both are great :-)
BUT: I should revise my question:
I have a custom control where I defined the properties. Within the SAMe custom control I want to access these properties in a repeat control.
Both your answers seem to assume that the access to these properties is from the view (page) level, right?
I tested Svens way - this works if I access the props in the CC from the page level.
EDIT
So this is the code of the CC:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.properties>
<xp:parameter name="param" value="val"></xp:parameter>
</xp:this.properties>
<xp:label value="#{javascript:facesContext.getProperty('param')}"
id="label1">
</xp:label>
</xp:view>
As you can see I just want to access the property within the CC itselt, not from the page level.
You can get the properties by accessing facesContext:
facesContext.getProperty("index.xsp")
EDIT:
If you set the properties in a custom control, the properties are not added to the view root. The are set as attributes of the custom control (com.ibm.xsp.component.UIIncludeComposite).
To access them you first have to give your CC an Id:
<xc:ccProp id="myId" />
This allows you to access the custom control like a component with the getComponent() method and retrieve the attribute properties which contains the properties:
<xp:label id="labelProperty">
<xp:this.value><![CDATA[#{javascript:
var cc:com.ibm.xsp.component.UIIncludeComposite = getComponent("myId");
var arrList:java.util.ArrayList = cc.getAttributes().get("properties");
arrList.get(0).getName()}]]>
</xp:this.value>
</xp:label>
EDIT 2:
You can access the CC (which is the parent of the label in this example) this way if you don't want to give your CC an ID:
Code of the custom control:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.properties>
<xp:parameter name="param" value="val"></xp:parameter>
</xp:this.properties>
<xp:label id="label1">
<xp:this.value><![CDATA[#{javascript:
this.parent.getAttributes().get("properties").get(0).getName()
}]]></xp:this.value>
</xp:label>
<xp:label id="label2">
<xp:this.value><![CDATA[#{javascript:
this.parent.getAttributes().get("properties").get(0).getValue()
}]]></xp:this.value>
</xp:label>
</xp:view>
Hope this helps to clarify the issue.
To get the property list you can use the view.getProperties(). It returns an object of java.util.List which you can use to loop through individual properties (which are objects of com.ibm.xsp.complex.Parameter). Below is the snippet.
var allProperties:java.util.List = view.getProperties();
for (var i=0 ; i<allProperties.size() ; i++) {
var property:com.ibm.xsp.complex.Parameter = allProperties.get(i);
// property.getName();
// property.getValue();
}
If you want to put it in a repeat then you can bind it to view.getProperties() and then get its individual values. You code would then look something like this:
<xp:repeat rows="30" value="#{javascript:view.getProperties()}" var="property">
<xp:text escape="true">
<xp:this.value><![CDATA[#{javascript:property.getName() + " - " + property.getValue();}]]></xp:this.value>
</xp:text>
<xp:br></xp:br>
</xp:repeat>
If you've got values that you want to use on the various parts of an Xpage, whether directly on the page, in a custom control, or in a repeat, I would recommend that you put the values into sessionScope variables. This allows you to change them easily as the user enters information on the Xpage.
For example, sessionScope.PODocUNID = poDoc.getDocument().getUniversalID(); would put the UNID of the purchase order document that I'm working with into a sessionScope variable named PODocUNID. Then, you can pull up the value any time you want by simply referencing sessionScope.PODocUNID in your code.
Alternatively, you could use Russ Maher's current favorite toy, the Managed Bean (see his three-part video on Notes in 9, starting at: http://notesin9.com/index.php/2012/11/02/notesin9-084-sharing-managed-beans-in-xpages/ )
Is it possible to do something like this
while (view.mouseover == true) {
preform action
}
I want to have an action repeat for as long as the mouse is over a specific view.
(asked on the laszlo-user mailing list)
Well, it looks like you answered your own question while I was testing my solution to make sure it worked correctly, but here is an alternative solution that works under OpenLaszlo 4.9.0 SWF10 and OpenLaszlo 4.9.0 DHTML run-times:
<canvas width="1000" height="665" debug="true">
<view id="v" bgcolor="0xcccccc" width="200" height="200">
<!--- #param boolean mouseisover: true when the mouse is over -->
<attribute name="mouseisover" type="boolean" value="false" />
<!--- #keywords private -->
<!--- #param lz.Delegate dlgt_repeat: stores the lz.Delegate object -->
<attribute name="dlgt_repeat" type="expression" />
<!--
Called when the 'onmouseover' event occurs
-->
<handler name="onmouseover">
// Step 1) unregister any existing delegate
// mark it for garbage collection
// and prevent its event from triggering:
if (this['dlgt_repeat'])
this.dlgt_repeat.unregisterAll();
// Step 2) update this.mouseisover flag:
if (!this.mouseisover)
this.setAttribute('mouseisover', true);
// Step 3) create an event Delegate and call it
// on the next application idle event:
var objDlgt = new lz.Delegate(this, 'doSomething');
this.setAttribute('dlgt_repeat', objDlgt);
lz.Idle.callOnIdle(this.dlgt_repeat);
</handler>
<!--
Called when the 'onmouseout' event occurs
-->
<handler name="onmouseout">
// Step 1) unregister any existing delegate
// mark it for garbage collection
// and prevent its event from triggering:
if (this['dlgt_repeat'])
this.dlgt_repeat.unregisterAll();
// Step 2) Update this.mouseisover flag:
if (this.mouseisover)
this.setAttribute('mouseisover', false);
</handler>
<!--- #keywords private -->
<!---
Called on application idle event by lz.Idle repeatedly
when the mouse is down.
#param ??? objDummy: required for SWF9+ run-times for methods
called by delegates due to AS3 (ActionScript3 compiler
requirements). Just set default to null to make compiler
happy and ignore...
-->
<method name="doSomething" args="objDummy=null">
<![CDATA[
// Note: CDATA allows '&&' to be used in script below,
// alternatively omit CDATA and use '&&' instead
// of '&&'
// Step 1) Execute your code you want to run here:
if ($debug) Debug.debug('Do something...');
// Step 2): If mouse is still over and the event
// delegate exists then schedule the event to be
// executed upon the next application idle state:
if (this.mouseisover && this['dlgt_repeat'] != null)
lz.Idle.callOnIdle(this.dlgt_repeat);
]]>
</method>
<text text="Move mouse over" />
</view>
</canvas>
Since both ActionScript and JavaScript are single threaded, it's not possible to have a while loop with pauses between each loop iteration. In the SWF10/11 runtime, you need to make sure that the code within each method or function can be executed within one frame (duration depends on the framerate of the SWF clip) of your application.
As a workaround you can use a timer, here is an example:
<canvas debug="true">
<class name="mouseoverview" extends="view"> <attribute name="timer" type="object" value="null" />
<!-- lz.Delegate instance used by the timer -->
<attribute name="timerdel" type="object" value="null" />
<attribute name="timeractive" type="boolean" value="false" />
<!-- milliseconds to pause before each call to doWhileMouseover method -->
<attribute name="tick" type="number" value="500" />
<handler name="onmouseover">
Debug.info('mouseover');
if (this.timeractive == false) {
this.setAttribute('timeractive', true);
this.timerdel = new lz.Delegate( this, "timerCallback" );
this.timer = lz.Timer.addTimer( this.timerdel, this.tick );
// When the timer is activated, do one call to the method
// containing the loop logic. The following calls will be
// handled by the timer and delegate.
this.doWhileMouseover();
}
</handler>
<handler name="onmouseout">
Debug.info('mouseout');
if (this.timeractive) {
this.setAttribute('timeractive', false);
lz.Timer.removeTimer(this.timerdel);
}
</handler>
<method name="timerCallback" args="millis">
if (this.timeractive) {
lz.Timer.resetTimer(this.timerdel, this.tick);
this.doWhileMouseover();
}
</method>
<method name="doWhileMouseover">
Debug.info("This is your virtual while loop for mouseover");
</method>
</class>
<mouseoverview x="100"
y="100"
width="400"
height="400"
bgcolor="#33aaff"
tick="250">
</mouseoverview>
</canvas>
When a mouseover occurs, a timer is started using the timerdel (an instance of lz.Delegate). Then the doWhileMouseover() method is called once directly, and then repeatedly using the timer, as long as no onmouseout event happened.