0

Tridion にスキーマがあり、スキーマ フィールドが埋め込まれており、そこにさらにフィールドが埋め込まれている可能性があります。

値を割り当てることができるように、最終的なリーフ フィールドに到達したいと考えています。そのために、最終フィールドに到達するまですべてのフィールドをループする再帰関数を書きたいと思います。

SDL Tridion 2011 の Core Service を使用して実装しています

私のコード:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ServiceModel;
using System.Net;
using System.Xml;
using Tridion.ContentManager.CoreService.Client;
using System.Text;
using Tridion.ContentManager.CoreService;
using System.ServiceModel.Channels;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using System.Data.OleDb;
using System.Data;
using System.Configuration;


namespace Loading_Utility
{
    public partial class TST : System.Web.UI.Page
    {
        Fields obj = new Fields();
        protected void Page_Load(object sender, EventArgs e)
        {
            using (ChannelFactory<ISessionAwareCoreService> factory =
            new ChannelFactory<ISessionAwareCoreService>("wsHttp_2011"))
            {
                ISessionAwareCoreService client = factory.CreateChannel();
                var schemaFields = client.ReadSchemaFields("tcm:202-2242-8", true, new ReadOptions());
                ComponentData component = (ComponentData)client.GetDefaultData(ItemType.Component, "tcm:202-638-2");
                var fields = Fields.ForContentOf(schemaFields);
                component.Schema.IdRef="tcm:202-2242-8";
            }
        }
        public void fieldRecursion(Field field)
        {
            //var getFields = fields;
            if (field.GetType() == typeof(EmbeddedSchemaFieldDefinitionData))
            {
                // code for checking further if field is embedded or not


                //Field newField = field.GetSubFields().GetFieldElements( new ItemFieldDefinitionData() as Field)
                //fieldRecursion(recursiveField);
            }
            //string fieldName = recursiveField.Name;
            //fields[fieldName] = "HI";

        }
    }
}
4

2 に答える 2

3

お探しのソリューションはありませんが、コア サービスを使用しているようです。個人的には、コンポーネント XML (Component.Content) を取得し、必要に応じて解析/操作することを好みます。XML をここに貼り付けていただければ、私のサンプル コア サービス プロジェクトの 1 つにドロップして、ソリューションを返送できますか?

役に立たない場合は、API を確認しました。これは、正しい道を歩むのに役立つはずです。おそらく解決策があれば、ここに貼り付けることができますか?

public void RecurseEmbeddedFields(SchemaFieldsData schemaFields)
{
    foreach (ItemFieldDefinitionData field in schemaFields.Fields)
    {
        if (field.GetType() == typeof(EmbeddedSchemaFieldDefinitionData))
        {
            // check if this field contains more embedded fields
            // if it does recurse
        }
    }
}
于 2012-05-09T04:48:01.220 に答える
1

OK、私は助けていないことに少し罪悪感を感じましたが、これはTridion関連の質問ではなく、一般的な開発手法についてもう少し経験を積む必要があるという私の見解を支持しています。

コンポーネントのコンテンツをロードし、Xmlを使用して再帰的に読み取る方法の例を次に示します。

コンポーネントのXML:

<Content xmlns="uuid:02395f72-acef-44e8-9c35-ff8c9f380251">
    <EmbeddedSchema1>
        <SomeField>Hello</SomeField>
        <EmbeddedSchema2>
            <ATextField>There</ATextField>
        </EmbeddedSchema2>
    </EmbeddedSchema1>
</Content>

コアサービスコード:

static void Main(string[] args)
{
    SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient("wsHttp_2011");
    ReadOptions readOptions = new ReadOptions();

    ComponentData component = (ComponentData)client.Read("tcm:5-3234", readOptions);
    Console.WriteLine("Find fields recursively");

    XmlDocument content = new XmlDocument();
    content.LoadXml(component.Content);
    SchemaData schema = (SchemaData)client.Read(component.Schema.IdRef, readOptions);
    XmlNamespaceManager ns = new XmlNamespaceManager(new NameTable());
    ns.AddNamespace("content", schema.NamespaceUri);

    foreach (XmlElement node in content.SelectNodes("content:*", ns))
    {
        ReadContentRecursively(node, ns);
    }
    client.Close();
}
private static void ReadContentRecursively(XmlElement node, XmlNamespaceManager ns)
{
    if(!string.IsNullOrEmpty(node.InnerText))
    {
        foreach (XmlNode innerNode in node)
        {
            if(innerNode is XmlText)
            {
                Console.WriteLine("Node " + node.Name + " with value \"" + innerNode.Value + "\"");
            }
        }
    }
    if(node.SelectNodes("content:*", ns).Count > 0)
    {
        foreach (XmlElement childNode in node.SelectNodes("content:*", ns))
        {
            Console.WriteLine("Found Field: " + childNode.Name);
            ReadContentRecursively(childNode, ns);
        }
    }
}

ReadContentRecursivelyが自分自身を呼び出す方法に注意してください。

お役に立てれば。

于 2012-05-09T20:29:30.767 に答える