5

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

我期待类似的东西:

   <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 的新手,所以很少详细的答案会很有帮助。

4

2 回答 2

6

根据您的实际需要,有很多简单的方法可以做到这一点,但我使用以下用 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 结构。

于 2013-03-06T05:18:23.247 回答
4

由于 Tridion 灵活的数据模型,您实际上要求回答一个相当困难的问题。

有几件事是肯定的:

  • 有页
    • 页面具有标题、ID、URL、发布 ID、版本、创建日期、发布日期等属性
  • 页面可能有组件展示
    • 组件演示中有内容

一个组件(或一组组件)的内容很可能是您要搜索的内容,因为这是您希望在网站上显示的数据。组件在 Tridion 内容管理器中存储为 XML,并在发布时通过模板进行转换。组件使用的 XML 模式由实现者定义(因此所有实现都可能使用不同的模式),转换该组件的模板也由实现者定义 - 因此所有实现都可能具有不同的输出。

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

  1. 根据您的网站要求为您的内容定义架构
  2. 定义一个模板,将您的内容作为 XML 发布到交付层

(我在这里简化了很多 - 不要低估为任何给定组织定义适当内容模型所需的工作)

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

于 2013-03-06T14:14:22.847 回答