string.Replace symbols - c#

i want to replace some symbols in fetchxml query
Fetchxml.Replace("\"", "'").Replace("\n", "\"+").Replace("<", "\"<");
I want to replace \n (return to the line) with "+
and replace the < with "<
But
the Replace("\n", "\"+") that doesn't work it still \n
and the Replace("<", "\"<") it replace the < with \"< istead of "<
Sample XML:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"> <entity name="account"> <attribute name="name" /> <filter type="and"> <condition attribute="statecode" operator="eq" value="0" /> </filter> <link-entity name="contact" from="contactid" to="primarycontactid" visible="false" link-type="outer" alias="accountprimarycontactidcontactcontactid"> <attribute name="emailaddress1" /> </link-entity> </entity> </fetch>
Desired output:
<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"+ "<entity name='account'>"+ "<filter type='and'>"+ "<condition attribute='statecode' operator='eq' value='0' />"+ "</filter>"+ "</entity>"+ "</fetch>

It looks what you're trying to do is simply insert '+' into the text elements of this XML. This is a bit of an odd thing to be doing, but I'll bite.
I would suggest this is easy in Perl, using XML::Twig. The problem with XML is it doesn't parse easily with regex, but it does parse easily with an XML parser.
So given input XML of:
<fetch distinct="false" mapping="logical" output-format="xml-platform" version="1.0">
<entity name="account">
<attribute name="name"/>
<filter type="and">
<condition attribute="statecode" operator="eq" value="0"/>
</filter>
<link-entity alias="accountprimarycontactidcontactcontactid" from="contactid" link-type="outer" name="contact" to="primarycontactid" visible="false">
<attribute name="emailaddress1"/>
</link-entity>
</entity>
</fetch>
It can be turned into a close approximation of your desired output XML:
#!/usr/bin/perl
use strict;
use warnings;
my $xml = XML::Twig->new(
'pretty_print' => 'indented',
'twig_handlers' => {
'attribute' => sub { $_->delete },
'link-entity' => sub { $_->delete },
},
);
$xml->parse( \*DATA );
$xml ->print;
This gives you:
<fetch distinct="false" mapping="logical" output-format="xml-platform" version="1.0">
<entity name="account">
<filter type="and">
<condition attribute="statecode" operator="eq" value="0"/>
</filter>
</entity>
</fetch>
(If you don't want it line separated and indented, turn off that pretty_print flag)
Now, I'm not entirely sure what you're trying to accomplish with the + symbols there. Are you perhaps trying to quote your XML result? In all honesty, that doesn't really make an awful lot of sense from an XML perspective.
If you really had to though, I guess you could:
my $output_xml = $xml ->sprint;
$output_xml =~ s/^\s+//gm;
$output_xml =~ s/\n</"+ "</g;
print $output_xml;
Which would give you:
<fetch distinct="false" mapping="logical" output-format="xml-platform" version="1.0">"+ "<entity name="account">"+ "<filter type="and">"+ "<condition attribute="statecode" operator="eq" value="0"/>"+ "</filter>"+ "</entity>"+ "</fetch>

Related

Avoid Aliases in result from FetchXml with linked entities

I have the following FetchXML:
<fetch>
<entity name="list" >
<attribute name="listname" />
<attribute name="listid" alias="List" />
<filter type="and" >
<condition attribute="listname" operator="eq" value="Test 1" />
</filter>
<link-entity name="listmember" from="listid" to="listid" intersect="true" alias="listmember" >
<attribute name="entitytype" />
<attribute name="listmemberid" />
<attribute name="entityid" />
<link-entity name="contact" from="contactid" to="entityid" alias="contact" >
<attribute name="contactid" />
<attribute name="owneridname" />
<attribute name="owneridtype" />
<attribute name="ownerid" />
</link-entity>
</link-entity>
</entity>
The result looks like this:
<resultset morerecords="0" paging-cookie="<cookie page="1"><listid lastnull="1" firstnull="1" /></cookie>">
<result>
<listname>Test 1</listname>
<listmember.entitytype formattedvalue="2">2</listmember.entitytype>
<listmember.listmemberid>{6739D9B9-xxxx-xxxx-xxxx-000D3A3852A3}</listmember.listmemberid>
<listmember.entityid type="2">{039FD4C6-xxxx-xxxx-xxxx-000D3A385A1C}</listmember.entityid>
<contact.contactid>{039FD4C6-xxxx-xxxx-xxxx-000D3A385A1C}</contact.contactid>
<contact.ownerid name="CRM Test" dsc="" type="8" yomi="CRM Test">{5ABA5CBA-xxxx-xxxx-xxxx-D472F64781F6}</contact.ownerid>
</result>
</resultset>
My issue now is that I have a generic way to retrieve the attributes returned by a FetchXml. But since this one has linked entites the aliases are added to the result, like:
<listmember.listmemberid>
So my retrieve will throw an error since I am looking for "listmemberid"
Is there a way to avoid having these aliases added to the result? Specially since the attribute names are unique?
Any ideas to get around this issue?
The only option to override the alias of the select column which is working - when you do aggregate function and I tested the below working example.
<fetch top="50" aggregate="true" >
<entity name="account" >
<attribute name="businesstypecode" alias="test" groupby="true" />
<link-entity name="contact" from="accountid" to="accountid" link-type="inner" alias="acc" >
<attribute name="accountrolecode" alias="testing" groupby="true" />
</link-entity>
</entity>
</fetch>
Result:
test testing
1 3
1
This didn't work. I don't know why, maybe limitation of fetchxml.
<fetch top="50" >
<entity name="contact" >
<attribute name="fullname" />
<link-entity name="account" from="accountid" to="accountid" alias="acct" >
<attribute name="name" alias="acctNAME" />
</link-entity>
</entity>
</fetch>
Result:
fullname acct.name
arun account arun account
Even with the Query Expression, you will get a special datatype called AliasedValue to handle this, so this is intended behavior. Read more
You get these aliases and then it’s value because you are retrieving data from linked entity. Whenever you do that I.e retrieving from linked entity you will have to use aliases, as far as I know you cannot circumvent it.
What I could suggest is if you need data only from ListMember entity and not from List and contact,
Create your fetch based on list member entity such as
select * from listmember where listname="Test 1"
But as soon as you need data from related entity, that related entity shall be aliased.

C# Web Reference - ArrayOfString not serialising

I am using Web References in C# to interface with Magento, which uses a SOAP API. The WSDL contains lots of definitions as you can imagine, but I'm having a problem with this particular one:
<complexType name="ArrayOfString">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]"/>
</restriction>
</complexContent>
</complexType>
Any propertes of a method that are an ArrayOfString are being brought back to my code as string[], which is fine, but when serialising it back to Magento it's serialising it as below
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:Magento" xmlns:types="urn:Magento/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<tns:catalogProductCreate>
<sessionId xsi:type="xsd:string">xxxxxxxxxxxxxxxxxxxxxxx</sessionId>
<type xsi:type="xsd:string">simple</type>
<set xsi:type="xsd:string">63</set>
<sku xsi:type="xsd:string">CHRISTEST</sku>
<productData href="#id1" />
</tns:catalogProductCreate>
<tns:catalogProductCreateEntity id="id1" xsi:type="tns:catalogProductCreateEntity">
<categories href="#id2" />
<websites href="#id3" />
<name xsi:type="xsd:string">Chris Test 8</name>
<description xsi:type="xsd:string">fsd</description>
<short_description xsi:type="xsd:string">Chris Test 8</short_description>
<weight xsi:type="xsd:string">0.0000</weight>
<status xsi:type="xsd:string">1</status>
<visibility xsi:type="xsd:string">1</visibility>
<category_ids href="#id4" />
<website_ids href="#id5" />
<price xsi:type="xsd:string">0.00000</price>
<tax_class_id xsi:type="xsd:string">4</tax_class_id>
<tier_price href="#id6" />
</tns:catalogProductCreateEntity>
<soapenc:Array id="id2" soapenc:arrayType="xsd:string[0]" />
<soapenc:Array id="id3" soapenc:arrayType="xsd:string[0]" />
<soapenc:Array id="id4" soapenc:arrayType="xsd:string[1]">
<Item>35</Item>
</soapenc:Array>
<soapenc:Array id="id5" soapenc:arrayType="xsd:string[1]">
<Item>1</Item>
</soapenc:Array>
<soapenc:Array id="id6" soapenc:arrayType="tns:catalogProductTierPriceEntity[0]" />
</soap:Body>
</soap:Envelope>
And this is resulting in the arrays being ignored. I believe the reason the ArrayOfString entity isn't being added to my service model is because it has a 'restriction', but I'm going to need this to get the data back to Magento. Any ideas guys?

Access second level linked entity from FetchXML

Here is the fetchXML:
<fetch version='1.0' mapping='logical' distinct='true'>
<entity name='listmember'>
<link-entity name='contact' from='contactid' to='entityid' alias='c'>
<attribute name='contactid' />
<attribute name='telephone1' />
<link-entity name='phonecall' from='ic_customer' to='contactid' alias='pc' link-type='outer'>
<attribute name='activityid' />
<attribute name='ic_end' />
<filter type='and'>
<filter type='or'>
<condition attribute='statuscode' operator='eq' value='1' />
</filter>
</filter>
</link-entity>
<filter type='and'>
<condition attribute='statecode' operator='eq' value='0' />
<condition attribute='telephone1' operator='not-null' />
<condition attribute='donotphone' operator='eq' value='0' />
</filter>
</link-entity>
<filter type='and'>
<condition attribute='listid' operator='in'><value>{ed0fa81c-1b65-e611-80ee-5065f38be311}</value></condition>
<condition entityname='pc' attribute='activityid' operator='null' />
</filter>
</entity>
</fetch>
Now I want to access the ic_end attribute when I got object through RetrieveMultiple method in C#.
I tried to get attribute via:
var endDate = (DateTime)((AliasedValue)contact["c.pc.ic_end"]).Value;
I got an error that no attribute with that name was found.
Any suggestions?
Few things here:
First and foremost the way you retrieve the linked-entity attribute is incorrect, the attributes are returned in a format of alias.attributename (pc.ic_end in this case).
Also always check if the attribute exists based on your join criteria it may not always be returned. Retrieve attribute logic should be along the lines of:
if (contact.Attributes.Contains("pc.ic_end") &&
contact.Attributes["pc.ic_end"] != null)
{
var endDate = (DateTime) ((AliasedValue) contact["pc.ic_end"]).Value;
}
link-entity name='phonecall' from='ic_customer' to='contactid'
alias='pc' link-type='outer'
I got an error that no attribute with that name was found.
As soon as you have the link-type specified as outer, all contacts With OR Without phone call records are returned. So this is an intended behaviour, you would need to check if the attribute exists in the attribute list returned.
If you want the query to only ever return a contact record With a phone call, use a natural inner join
<link-entity name='phonecall' from='ic_customer' to='contactid' alias='pc'>

How do I build FetchXML to give me all members of list A outer joined with all members of list B by emailaddress1

And is that even possible?
I have the fetch xml already to filter list B out of list A by record id however I also want the option to filter it by the email address.
For example:
List A has 2 records. Record 1: Bob#BobMail.com and Record 2: Susy#SusyMail.com.
List B has 1 record. Record 3 Bob#BobMail.com which is a different contact than Record 1 but has the same email address.
Still with me? Sorry for the confusing explanation...
The query should take List A, do an outer join with List B to produce the result which only contains Record 2 with the email address Susy#SusyMail.com.
If there's any way I can be more clear on what I'm trying to do don't hesitate to ask.
After a night to think about it and a fresh pair of eyes in the morning I realized I simply needed to link the listmember to the contact exactly as I had been with the by ID option and then add an additional link to the contact entity on the email address.
<fetch mapping="logical" version="1.0" page="1" count="100" >
<entity name="contact" >
<link-entity name="listmember" from="entityid" to="contactid" >
<filter>
<condition attribute="listid" operator="eq" value="06197bff-a299-e311-aae4-6c3be5a892e8" />
</filter>
</link-entity>
<attribute name="contactid" />
<attribute name="emailaddress1" />
<filter type="and" >
<condition attribute="emailaddress1" operator="not-null" />
<condition attribute="donotbulkemail" operator="ne" value="1" />
</filter>
<link-entity name="listmember" from="entityid" to="contactid" link-type="outer" alias="exclusionlist" >
<attribute name="entityid" />
<filter type="and" >
<condition attribute="listid" operator="eq" value="06197bff-a299-e311-aae4-6c3be5a892e8" />
</filter>
</link-entity>
<link-entity name="contact" from="emailaddress1" to="emailaddress1" link-type="outer" alias="emailaddress" >
<attribute name="fullname" />
<attribute name="emailaddress1" />
</link-entity>
<order descending="false" attribute="emailaddress1" />
</entity>
And then we filter out the reults by the alias:'
results = results.Where(x => !x.Contains("exclusionlist.entityid") || !x.Contains("emailaddress.emailaddress1")).ToList();
Hopefully this helps someone else though I do feel a bit dumb for asking now...

CRM 4.0 - FetchXML to retrieve data from related entity

I'm trying to use FetchXML to pull in a list of courses with an 'entry year' related entity. What I would like to do is only return a single record for each course (could return multiple courses) with the latest year (e.g I would want it to pick the last year out of 2012, 2013, 2014 - so in this case 2014). So I currently have:
<fetch mapping="logical" distinct="true">
<entity name="course">
<all-attributes/>
<order attribute="name" />
<link-entity name="course_entryyear" from="courseid" to="courseid">
<link-entity name="entryyear" from="entryyearid" to="entryyearid">
<attribute name="year" />
</link-entity>
</link-entity>
</entity>
</fetch>
Is this possible to do within FetchXML and if so how can I amend the above?
Cheers
What about adding count="1" and inner join to the linked entities along with some ordering:
So it would look like:
<fetch mapping="logical" distinct="true">
<entity name="course">
<all-attributes/>
<order attribute="name" />
<link-entity name="course_entryyear" from="courseid" to="courseid" link-type="inner">
<link-entity name="entryyear" from="entryyearid" to="entryyearid" link-type="inner" count="1">
<attribute name="year" />
<order attribute="year" descending="true"/>
</link-entity>
</link-entity>
</entity>
</fetch>
Depending on how you are displaying the course list you might want to change the link-type for the "course-entryyear" from inner to outer, so that all courses get displayed even if they haven't been served yet.

Categories

Resources