I am trying to read the TCM ID from a multi value embedded field using Core Service. I would prefer to avoid using XML and string manipulation as much as possible and thought this was doable using the Fields class I have seen used before (https://github.com/NunoLinhares/TridionWebData/blob/master/ImportContentFromRss/ImportContentFromRss/Content/Fields.cs)
My main schema (Item Container) has a multi valued field called "items" which takes an embedded schema. The embedded schema has 2 fields: accountUrl (which takes a string) and icon (which is a ComponentLinkField). I want to find all components using Item Container and then in a loop get the TCM ID of the linked "icon" component. I will then Read the component from that TCM and check what Schema it is using. The issue is that when I run over my loop it will get only the first occurrence of "items" and will get the "icon" field TCM but then the loop will exit and it will grab the next component even if there are multiple "items" in the first Item Container.
// TCM ID of the main schema who's field we want to check
// Ex tcm: 8-44-8 is Item Container
string mainComponentSchemaTcm = "tcm:8-44-8";
// XML name of the schema field we want to check
string checkComponentField = "icon";
// Schema of the linked component we want to know if it is used in checkComponentField
string linkedComponentSchema = "Image";
// Are we checking embedded fields?
bool checkEmbeddedFields = true;
// If we are checking embedded fields what is the parent field/attribute holding the embedded field(s)
string parentField = "items";
// Creating the core service.
// Using "wsHttp_2013" binding to create the client, Other bindings (like "netTcp_2013") could be used depending on the need.
SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient("wsHttp_2013");
// Set up our search query filter to look only for components
SearchQueryData filter = new SearchQueryData();
filter.ItemTypes = new ItemType[] { ItemType.Component };
// In our case we only want components using a specific schema so we use it's TCM ID
// We use BasedOnSchemaData to get all the schema information and then set the filter above
// to use this specific schema
BasedOnSchemaData mainSchema = new BasedOnSchemaData();
mainSchema.Schema = new LinkToSchemaData() { IdRef = mainComponentSchemaTcm };
filter.BasedOnSchemas = new BasedOnSchemaData[] { mainSchema };
// Get the schema fields of our main schema using mainComponentSchemaTcm.
// Ex tcm: 8-44-8 is Item Container which contains the field "items"
// we also need to set whether we are checking and expanding embedded fields.
// For our Item Container "items" uses embedded fields "AccountURL" and "icon"
SchemaFieldsData schemaFields = client.ReadSchemaFields(mainComponentSchemaTcm, checkEmbeddedFields, new ReadOptions());
// Get list of components using our filter
var componentSearchResults = client.GetSearchResults(filter);
// We want to check each component in our results
foreach (var component in componentSearchResults)
{
var currentItem = (ComponentData)component;
// currentItem does not contain complete data for current component so we need to read the full data with client.Read
ComponentData compReadData = (ComponentData)client.Read(currentItem.Id, new ReadOptions());
// get content of component/schema fields for current component
var fieldsContent = Fields.ForContentOf(schemaFields, compReadData);
string tcmOfIcon = "";
foreach (var field in fieldsContent)
{
if (!string.IsNullOrEmpty(field.Value))
{
tcmOfIcon = field[checkComponentField].Value;
}
}
}
This code is incomplete but the main issue is the foreach (var field in fieldsContent) will only execute one time per component. Is this possible to do the way I'm trying or is the only way to parse through the XML?
Thanks for looking!