SDL Tridion:XML格式的页面的逻辑结构

时间:2013-03-06 01:21:32

标签: xml tridion

是否可以以xml格式提取SDL Tridion页面的信息,包括与其关联的内容。

我期待类似的东西:

   <page name="mypagename">
     <page id="xxxxx"/>
     <template name="abc" id="123">
        <container name="xyz">
          <content name="asd" id="123">
           <Path="" \>
          </content>
        </container>
     </template>
    </page>

技术堆栈是Tridion 2011和Java。

我是Tridion的新手,所以很少有详细的答案会有很大的帮助。

2 个答案:

答案 0 :(得分:6)

根据您的实际需要,有 MUCH 这样做的简单方法,但我使用以C#编写的以下TBB类构建基于组件模板元数据划分为内容区域的页面XML

class GetPageXML : TemplateBase
    {
        public override void Transform(Engine engine, Package package)
        {
            Initialize(engine, package);
            Logger.Debug("This will get the full page XML");
            Item pageItem = m_Package.GetByType(ContentType.Page);

            Page currentPage = GetPage();

            m_Engine.PublishingContext.RenderContext.ContextVariables.Add("CURRENT_PAGE", currentPage);


            XmlDocument pageXml = pageItem.GetAsXmlDocument();
            foreach (XmlNode cpNode in pageXml.SelectNodes("/tcm:Page/tcm:Data/tcm:ComponentPresentations/tcm:ComponentPresentation", NSManager))
            {
                TcmUri componentURI = new TcmUri(cpNode.SelectSingleNode("tcm:Component/@xlink:href", NSManager).Value);
                TcmUri componentTemplateURI = new TcmUri(cpNode.SelectSingleNode("tcm:ComponentTemplate/@xlink:href", NSManager).Value);

                //Render the componentPresentation
                XmlNode cpRenderElement = pageXml.CreateElement("tcm", "RenderedComponentPresentation", "http://www.tridion.com/ContentManager/5.0");
                XmlAttribute attNamespace = pageXml.CreateAttribute("xmlns:tcdl");
                attNamespace.Value = "http://www.tridion.com/ContentDelivery/5.3/TCDL";
                cpRenderElement.Attributes.Append(attNamespace);


                if (m_Engine.PublishingContext.RenderContext.ContextVariables.Contains("ORDINAL_POSITION"))
                {
                    int ordinalPosition = ((int)m_Engine.PublishingContext.RenderContext.ContextVariables["ORDINAL_POSITION"]) + 1;
                    m_Engine.PublishingContext.RenderContext.ContextVariables["ORDINAL_POSITION"] = ordinalPosition;
                //    m_Engine.PublishingContext.RenderContext.ContextVariables["ORDINAL_POSITION"] = 0;
                }
                else
                {
                    m_Engine.PublishingContext.RenderContext.ContextVariables.Add("ORDINAL_POSITION", 0);
                }


                //Get the metadata from the CT
                ComponentTemplate componentTemplate = (ComponentTemplate)m_Engine.GetObject(componentTemplateURI);
                String metadataXmlString = "";
                String cpRegionName = "";
                if (componentTemplate.Metadata != null)
                {
                    metadataXmlString = componentTemplate.Metadata.OuterXml;
                    XmlNode cpRegionNode = componentTemplate.Metadata.SelectSingleNode("//*[local-name()='region']");
                    if (cpRegionNode != null)
                    {
                        cpRegionName = "_" + cpRegionNode.InnerText;
                    }
                }
                cpNode.SelectSingleNode("tcm:ComponentTemplate", NSManager).InnerXml = metadataXmlString;



                String REGIONAL_POSITION = "REGIONAL_POSITION" + cpRegionName;
                if (m_Engine.PublishingContext.RenderContext.ContextVariables.Contains(REGIONAL_POSITION))
                {
                    int regionalPosition = ((int)m_Engine.PublishingContext.RenderContext.ContextVariables[REGIONAL_POSITION]) + 1;
                    m_Engine.PublishingContext.RenderContext.ContextVariables[REGIONAL_POSITION] = regionalPosition;
                    //    m_Engine.PublishingContext.RenderContext.ContextVariables["ORDINAL_POSITION"] = 0;
                }
                else
                {
                    m_Engine.PublishingContext.RenderContext.ContextVariables.Add(REGIONAL_POSITION, 0);
                }



                DateTime cpRenderStart = DateTime.Now;
                string contentCP = m_Engine.RenderComponentPresentation(componentURI, componentTemplateURI);

                DateTime cpRenderEnd = DateTime.Now;
                TimeSpan cpRenderTime = cpRenderEnd.Subtract(cpRenderStart);

                XmlAttribute attCPRenderTime = pageXml.CreateAttribute("RenderTime");
                attCPRenderTime.Value = String.Format("{0:0000}", cpRenderTime.TotalMilliseconds) + " milliseconds";
                cpNode.Attributes.Append(attCPRenderTime);


                if (m_Engine.RenderMode != RenderMode.Publish)
                {
                    //Remove the '&' symbols created for linking in previewmode
                    contentCP = contentCP.Replace("&", "");

                }

                try
                {
                    cpRenderElement.InnerXml = contentCP;
                }
                catch (Exception e)
                {
                    cpRenderElement.InnerXml = "Malformed XML in the output:" + e.Message;// +"<!--" + contentCP + "-->";
                }
                cpNode.AppendChild(cpRenderElement);



                Component component = (Component)m_Engine.GetObject(componentURI);
                XmlAttribute attComponentRevisionDate = pageXml.CreateAttribute("ModifiedOn");
                attComponentRevisionDate.Value = component.RevisionDate.ToString("yyyy-MM-dd HH:mm:ss tt");
                cpNode.Attributes.Append(attComponentRevisionDate);



                //Get the metadata from the Component

                metadataXmlString = "";
                if (component.Metadata != null)
                {
                    metadataXmlString = component.Metadata.OuterXml;
                }

                cpNode.SelectSingleNode("tcm:Component", NSManager).InnerXml = metadataXmlString;
            }



            //Add the rendered/published time
            XmlAttribute attRenderTime = pageXml.CreateAttribute("RenderedAt");
            attRenderTime.Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss tt");
            pageXml.DocumentElement.Attributes.Append(attRenderTime);

            //Add PublishInfo
            //Get the PublishTransaction

            PublishTransaction pubTrans = GetPublishTransaction(engine);

            if (pubTrans != null)
            {
                XmlElement nodePublisher = pageXml.CreateElement("Publisher");
                XmlElement nodePublisherName = pageXml.CreateElement("name");
                XmlElement nodePublisherId = pageXml.CreateElement("id");
                XmlElement nodePublisherDescription = pageXml.CreateElement("description");

                nodePublisherName.InnerText = pubTrans.Creator.Title;
                nodePublisher.AppendChild(nodePublisherName);

                nodePublisherId.InnerText = pubTrans.Creator.Id.ToString();
                nodePublisher.AppendChild(nodePublisherId);

                nodePublisherDescription.InnerText = pubTrans.Creator.Description;
                nodePublisher.AppendChild(nodePublisherDescription);

                pageXml.DocumentElement.AppendChild(nodePublisher);
            }

            //Add the target info
            if (engine.PublishingContext.PublicationTarget != null)
            {
                XmlElement nodePublicationTarget = engine.PublishingContext.PublicationTarget.ToXml();
                XmlNode nodePubs = nodePublicationTarget.SelectSingleNode("/tcm:PublicationTarget/tcm:Data/tcm:Publications", NSManager);
                nodePubs.ParentNode.RemoveChild(nodePubs);


                pageXml.DocumentElement.AppendChild(pageXml.ImportNode(nodePublicationTarget, true));
            }





            //Add the Page Modified time
            ModificationInfo modInfo = GetNewestModificationDateFromPageXml(pageXml);

            XmlAttribute attContentModifiedTime = pageXml.CreateAttribute("ContentLastModifiedOn");
            attContentModifiedTime.Value = modInfo.ModificationDate.ToString("yyyy-MM-dd HH:mm:ss tt");
            pageXml.DocumentElement.Attributes.Append(attContentModifiedTime);

            XmlAttribute attLastModifiedItem = pageXml.CreateAttribute("LastModifiedItemURI");
            attLastModifiedItem.Value = modInfo.ItemURI.ToString();
            pageXml.DocumentElement.Attributes.Append(attLastModifiedItem);

            XmlAttribute attLastModifiedTitle = pageXml.CreateAttribute("LastModifiedItemTitle");
            attLastModifiedTitle.Value = modInfo.ItemTitle;
            pageXml.DocumentElement.Attributes.Append(attLastModifiedTitle);




            //Add PageTemplate Properties
            XmlNode nodePageTemplate = pageXml.SelectSingleNode("/tcm:Page/tcm:Data/tcm:PageTemplate", NSManager);
            TcmUri uriPageTemplate = new TcmUri(nodePageTemplate.Attributes["href", "http://www.w3.org/1999/xlink"].Value);
            XmlElement pageTemplateXml = engine.GetObject(uriPageTemplate).ToXml(XmlSections.Data);
            nodePageTemplate.ParentNode.ReplaceChild(pageXml.ImportNode(pageTemplateXml, true), nodePageTemplate);

            //Add the publication properties
            XmlNode nodePublication = pageXml.SelectSingleNode("/tcm:Page/tcm:Context/tcm:Publication", NSManager);
            TcmUri uriPublication = new TcmUri(nodePublication.Attributes["href", "http://www.w3.org/1999/xlink"].Value);
            XmlElement publicationXml = engine.GetObject(uriPublication).ToXml(XmlSections.Data);
            nodePublication.ParentNode.ReplaceChild(pageXml.ImportNode(publicationXml,true), nodePublication);
            m_Package.PushItem("UrbanCherryPageFrameWork", m_Package.CreateXmlDocumentItem(ContentType.Xml,pageXml));
        }

你可以在XmlDocument pageXml = pageItem.GetAsXmlDocument();行停下来,只需将该值推入包中并称之为输出。

或者看看DD4T模板,因为它们也为页面输出标准的XML结构。

答案 1 :(得分:4)

由于Tridion灵活的数据模型,你实际上要求回答一件非常困难的事情。

有一些事情是肯定的:

  • 有页面
    • 页面包含标题,ID,URL,出版物ID,版本,创建日期,发布日期等属性
  • 页面可能具有组件演示文稿
    • 组件演示文稿中包含内容

组件(或组件集)的内容很可能是您要搜索的内容,因为这是您要在网站上显示的数据。组件在Tridion Content Manager中以XML格式存储,并在发布时由模板转换。组件使用的XML模式由实现者定义(因此所有实现都可能使用不同的模式),并且转换该组件的模板也由实现者定义 - 因此所有实现都可能具有不同的输出。 p>

因此,如果您想使用Tridion XML在交付层上构建网站,您需要:

  1. 根据您的网站要求定义内容的架构
  2. 定义一个模板,将您的内容作为XML发布到交付层
  3. (我在这里简化了很多 - 不要低估为任何特定组织定义正确的内容模型所需的工作)

    Chris为您提供了一个如何将XML推送到交付层的好例子。像DD4T这样的框架为您提供“免费”模板 - 但您仍然需要自己设计模式。