我正在使用Tridion 2011中的核心服务更新组件。
示例代码如下,
string COMPONENT_URI = "tcm:8-674";
string SCHEMA_URI = "tcm:8-426-8";
ComponentData component = client.TryCheckOut(COMPONENT_URI, null) as ComponentData;
try
{
Response.Write("<BR>" + component.Content);
XDocument xdoc = XDocument.Parse(component.Content);
var element = xdoc.Elements("first").Single();
element.Value = "updated";
xdoc.Save(component.Content);
client.Save(component, null);
Response.Write("<BR"+"SAVED");
}
catch (Exception ex)
{
Response.Write("Unable to save comp" + ex.Message);
}
client.CheckIn(COMPONENT_URI, null);
我遇到以下异常:
Unable to save compSequence contains no elements
详细说明:
first
- 组件中字段的名称
对此有任何帮助吗?
谢谢
答案 0 :(得分:12)
Tridion中的Component的XML具有以下格式:
<Content xmlns="uuid:2607D20D-1B22-4994-98C1-66D9ACF85C20">
<first>The value of my first field</first>
<second>The value of my second field</second>
</Content>
您的相关代码段是:
var element = xdoc.Elements("first").Single();
这无法选择元素,因为它是:
如果您没有指定命名空间,您似乎会期望自动选择默认命名空间,但这不是真的。只要您拥有处理命名空间的XML,每个查询都必须指定正确的命名空间。
如果你修改代码来处理这两个问题,它应该是这样的:
XNamespace ns = xdoc.Root.GetDefaultNamespace();
var element = xdoc.Descendants(ns+"first").Single();
您可能想要考虑阅读XML中的命名空间的.NET处理和一般的XML命名空间,因为这是一个非常常见的错误,您只需要快速离开系统。
在您发现给定here辅助类之前,想要通过核心服务更新组件XML的人。
此外,Mihai指出你调用XDocument.Save
的方式是错误的。它希望将文件名作为参数,同时将组件的XML传递给它。
答案 1 :(得分:3)
您的代码尝试将XML DOM保存到文件中。
XDocument.Save(string fileName)
- 将此XDocument
序列化到文件中,覆盖现有文件(如果存在)。
你应该使用这样的东西:
using (var client = new SessionAwareCoreServiceClient(netTcpBinding, remoteAddress))
{
ReadOptions readOptions = new ReadOptions();
ComponentData component = client.Read(compTcmUri, readOptions) as ComponentData;
XDocument dom = XDocument.Parse(component.Content);
// do your modifications to dom
component.Content = dom.ToString();
component = client.Update(component, readOptions) as ComponentData;
Console.WriteLine("Component updated: " + component.LocationInfo.WebDavUrl);
}
答案 2 :(得分:2)
有时,特别是如果要同步来自充当主服务器的其他存储库中的内容,则可以从头开始重新构建组件。 在这种情况下,这是一个如何做到这一点的基本例子:
public static void updateComponent()
{
string componentWdUrl = "/webdav/020%20Content/Building%20Blocks/Content/wstest/testComponent.xml";
CoreServicesUtil coreServicesUtil = new CoreServicesUtil();
coreServicesUtil.coreServiceClient.CheckOut(componentWdUrl, true, coreServicesUtil.readOptions);
ComponentData componentData = coreServicesUtil.getComponentData(componentWdUrl);
SchemaData schemaData = coreServicesUtil.getSchemaData(componentData.Schema.IdRef);
componentData.Content = xmlUtil.GetNewXmlNode("Content", schemaData.NamespaceUri);
componentData.Metadata = xmlUtil.GetNewXmlNode("Metadata", schemaData.NamespaceUri);
componentData.AddSingleField("singlefield", "singlefield sample", schemaData.NamespaceUri);
componentData = (ComponentData)coreServicesUtil.coreServiceClient.Save(componentData, coreServicesUtil.readOptions);
coreServicesUtil.coreServiceClient.CheckIn(componentData.Id, coreServicesUtil.readOptions);
coreServicesUtil.coreServiceClient.Close();
}
有关此示例中使用的方法的更多说明,请参阅文章:
Faulted State error while creating component with Core Service