generating xml containg fields of a component in sdl tridion - tridion

How to generate xml file which contain all the fields of a component in SDl Tridion?
I have to do this by writing C# code.
I am using the following code:
public class stockcompany : ITemplate
{
private Engine engine;
private Package package;
public void Transform(Engine engine, Package package)
{
this.engine = engine;
this.package = package;
StringBuilder sb = new StringBuilder();
Component component = engine.GetObject(package.GetValue("Component.ID")) as Component;
ItemFields componentfields = new ItemFields(component.Content, component.Schema);
ItemFields compometa = new ItemFields(component.Metadata, component.Schema);
if (compometa.Contains("check"))
{
}
if (componentfields.Contains("companyname"))
{
string company = string.Empty;
company = componentfields["companyname"].ToString();
package.PushItem("xml", package.CreateHtmlItem(company.ToString()));
XDocument myxml = new XDocument (new XDeclaration ("1.0","UTF-8",null ),new XElement ("companies",new XElement ("company",xml)));
}

You are probably re-inventing the wheel here.
Tridion items are XML. The .Content and .Metadata properties of a component return XML, would this be enough?
DD4T uses templates that publish XML to the delivery side, might be worth checking it: http://code.google.com/p/dynamic-delivery-4-tridion/
Given that DD4T is open sourced, you may want to check how they do it as an example.

Another approach to generating XML is to use an XmlSerializer. It works as follows:
Create a POCO
Fill it with values from the component
Use XmlSerializer to deserialize it into an XML string
Store the XML in the Output variable of the package
This is how DD4T does it. As Nuno said, it is worth while to check it out (see his answer).

I've typically resorted to XSLT to get source XML via a component template, but we can definitely do the same with C#.
[TcmTemplateTitle("Show XML Guts")]
public class ShowXmlGuts : ITemplate
{
public void Transform(Engine engine, Package package)
{
Item contentItem = package.GetByType(ContentType.Component);
Component component = engine.GetObject(contentItem.GetAsSource().GetValue("ID")) as Component;
package.PushItem("componentSource", package.CreateHtmlItem(component.Content.OuterXml));
}
}
Pick-and-Choose Fields
If at all possible, I'd start with an intermediate XML format that's not a one-to-one mapping to component source.
We're meant to get and transform fields with the appropriate APIs. Relying on the source component format could be problematic in your next major change, which could include:
schema changes and new keywords
presentation/rendering side or CMS changes
"unexpected" content (rich text, special characters, tcm references, etc)
Alternatives to C#
In terms of technology:
XSLT is great for "XML generation," even if done in a C# template building block.
The XSLT Mediator would a good choice, if allowed in your environment
You could create XML with DWT, simplifying field selection; however, it's easier to create invalid XML this way (XSLT doesn't validate your XML either, but it's slightly harder to break node nesting)
If possible, update your question with the output XML you're trying to achieve or start a new question to get from your raw component XML to desired output.

Your code isn't very clear and contains a lot of problems, but generally you seem to be on the correct track.
1) You need to cast your
componentfields["companyname"].ToString();
I suspect you're working with a TextField here so cast it to a TextField object and then use the objects .value property
2) Here is where you push the value into the package, this will contain whatever you got from your 'companyname' field, it could be xml, it may not be:
package.PushItem("xml", package.CreateHtmlItem(company.ToString()));
..But I think with this information you can find your way to what you need.
Good luck!

Related

Using code-first approach,I don't have an edmx file. what's the alternative?

I'm fairly new to asp.net mvc, so please bear with me.
I want to implement a calendar functionality, and all the tutorials I've looked at use database-first approach and have the edmx file (Entity Data Model)
I'm using code first and what can I do regarding the code that references this edmx file? do I reference context instead?
example:
public JsonResult GetEvents()
{
//Here MyDatabaseEntities is our entity datacontext (see Step 4)
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
var v = dc.Events.OrderBy(a => a.StartAt).ToList();
return new JsonResult { Data = v, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
Sorry if this question is vague or not clear.
Thank you and I'd appreciate help!
In code first, you don't need an edmx file, because everything is in your own code. The basic building blocks are:
A class that inherits from DbContext. This will be equivalent to the MyDatabaseEntities class in your sample.
A set of entity classes. They basically just need to be plain classes with auto properties corresponding to your database columns. For built in conventions to work, you also need an ID, for instance an int property named Id
A set of properties on your DbContext class of type DbSet for every type T which is an entity you would like to query against. This is the Events property in your example.
In more advanced scenarios you customize the mappings beyond what the conventions can infer automatically. This can be done with attributes on your entity classes, or via a special set of APIs that can be called on your context at startup
Go to Sql server inside your database there is a folder Database Diagram, Right click New Database Diagram and explore it.

How to get the user who initiated a publish action in a SDL Tridion C# TBB

From a C# TBB used by a Modular Page Template in SDL Tridion 2011, is it possible to access the User object who initiated the Publishing action?
Looking at the TOM.NET 6 Programmers Reference Guide, it seems that the property I need is the Creator property of the PublicationTransaction object, but I can’t find a way to access that from a C# TBB, I don’t see an obvious way to get the current PublicationTransaction from the engine or package objects, and I can only find a way to get a list of PublicationTransaction objects using the PublishEngine object.
Any advice would be greatly appreciated.
Have a look at these two blog posts from Mihai Cadariu:
How to look up the current Publish Transaction (based on a trick from Chris Summers)
Create a new Publish Transaction based on an existing one
With those two you should be able to find what you need.
The basic function you need in your TBB is this:
public PublishTransaction GetPublishTransaction(Engine engine)
{
String binaryPath = engine.PublishingContext.PublishInstruction.
RenderInstruction.BinaryStoragePath;
Regex tcmRegex = new Regex(#"tcm_\d+-\d+-66560");
Match match = tcmRegex.Match(binaryPath);
if (match.Success)
{
String transactionId = match.Value.Replace('_', ':');
TcmUri transactionUri = new TcmUri(transactionId);
return new PublishTransaction(transactionUri, engine.GetSession());
}
return null;
}
It might also be worth noting that the property engine.PublishingContext.PublishInstruction.RenderInstruction.BinaryStoragePath will return something different when rendering the coder in PreviewMode or from the Template Builder compared to when the code is running in the Publisher. To see the PublishTransaction URI in the BinaryStoragePath, you must attach your Visual Studio TBB Debug Project to the TcmPublisher.exe process in order for there to actually be a PublishTransaction object present, otherwise the BinaryStoragePath will just contain a generic path like ../preview.

Storage and Serialization in AS3 / Adobe Flex

Thought Id ask here before jumping into a problem on the Blackberry Playbook (Adobe Flex)
I have a search form and a SearchCriteria class representing the search form's input, for example:
public class SearchCriteria
{
private var firstname:String;
private var surname:String;
public function SearchCriteria()
{}
public function getFirst():String{
return firstname;
}
...
As the person fills out the form, I would like to cache a copy in memory of the SearchCriteria so that if there is a problem, or the user turns off their tablet, I could recreate the form when they log back in.
TL;dr version: Basically, what is the best way to Serialize and Deserialize objects in Actionscript 3? (particularly on the Blackberry Playbook)
Thanks
Phil
If you are asking specifically about serialization and deserialization I'd recommend AMF3 format.
It is used by SharedObject mentioned by Timofei Davydik. You can also serialize objects with ByteArray.writeObject() and then save the ByteArray to a file.
Note that if you want to use strongly typed object (recommended) you should annotate your model classes with [RemoteClass] metadata. If you don't want some properties to be serialized use [Transient] metadata.
You could serialize them to JSON format using the as3corelib library.
And then use SharedObject or SQLite (works well in Playbook).
Read about SharedObject class.

Flex/AS3 : Automatically instantiate package classes in an array (plugin classes)

This is my first time here, but I already found some good answers here, so I'd like to thank everyone.
I'm developping a small Flex application and I want to instantiate every class from a package into an array, so I can parse it afterwards. To clarify, I'm trying to ease a plugin management system for my application, with the old canProcess/doProcess routine :
My plugins are all in ONE package, including an abstract plugin class. First, I create one instance of every classes in this package (that's where I need help) and put them in an array. Then, whenever I need a plugin for an item, I parse every plugin class in my array with the canProcess method (the item is the parameter). If one plugin says yes, then I send the item to the doProcess method and stop parsing the array.
I know I could implement by hand every class in my package, but I'd prefer not bothering to do it.
Has anyone an idea ?
Thx
AS3 reflection doesn't allow you to list all classes in a package. You will have to write the class names to an (xml) file at the server, load it and then use getDefinitionByName to get Class objects from those strings and then instantiate them.
Consider the sample xml file:
<root package="boris.ratak">
<className>Plugin1</className>
<className>Plugin2</className>
<className>Plugin3</className>
</root>
load it with URLLoader and parse it like:
import flash.utils.getDefinitionByName;
var pack:String = String(xml.#package) + ".";
for each(var cl:String in xml.className)
{
var name:String = pack + String(cl.text());
var Type:Class = getDefinitionByName(name) as Class;
pluginArray.push(new Type());
}

JSON string to list or other usable format in asp.net 2.0

I have one JSON that is coming in a string format. I need to store it in a key-pair value or something like that. I am using asp.net 2.0 and can not use 3rd party DLL like Newtonsoft.Json.dll. I guess last option will be to use regular expression.
Can anybody please help me in this?
If you go to http://www.json.org/ and look towards the bottom of the page there are dozens of json libraries most of them open source, I believe they list 8 for C#. If you can not reference one of these libraries, I think your best bet would be to find one with a permissive license and simply add the code to your project.
Another idea is to look at the diagrams, grammer, and syntax at http://www.json.org/ and just write your own parser, but regex is NOT the way to do it. If you dont know how to write a parser you could look at one of the open source json libraries or start with something less complicated like a good CSV parser, here is a paper that looks pretty good: http://www.boyet.com/Articles/CsvParser.html
It is possible to serialize JSON using JScript in C# into key/value pairs. You need to add a few references to your project. They're part of the .NET framework, you just need to add the references to your project. You'll need:
Microsoft.JSript
Microsoft.Vsa
First, the usings at the top of your class:
using Microsoft.JScript;
using Microsoft.JScript.Vsa;
Then the Engine that will execute the script needs to be initialized somewhere in your 'Page' code-behind:
VsaEngine Engine = VsaEngine.CreateEngine();
Then you just create this method and call it by passing in your JSON object:
object EvalJScript(string JScript)
{
object result = null;
try
{
result = Microsoft.JScript.Eval.JScriptEvaluate(JScript, Engine);
}
catch (Exception ex)
{
return ex.Message;
}
return result;
}
The type of object returned (if JSON is passed in) is a 'JSObject'. You can access its values as key/value pairs. Read the MSDN documentation for more details on this object.
Here's an example of using the code:
string json = "({Name:\"Dan\",Occupation:\"Developer\"})";
JSObject o = EvalJScript(json) as JSObject;
string name = o["Name"] as string; // Value of 'name' will be 'Dan'
Could you use JScript.NET?
If so, should be easy enough with eval() - then just loop through the objects returned and translate into KeyValuePair's or whatever
You will need to use jscript.net as the code behind language, but other pages of your site should be fine to stay as c# if thats what you prefer.
As mentioned in previous comment, you will need to be aware of the security aspects and risks - only use eval if you trust the JSON you're parsing!

Resources