How do I know if I need an XDocument or XElement? - c#-4.0

I understand that they are very similar and that the XDocument represents a whole document and an XElement represents a fragment of a whole document, but they seem to be very similar when it comes to loading and querying/updating the data. I am going to have templates saved to a disk and when I load them, I want to query over them and insert,update, and delete sections of data be it attributes or elements. Does XDocument or XElement make a difference here? Does it make a difference if I build the template on the dynamically first?

For starters, they behave in a different way when loading a document, which means you'll have to write your queries in a different way when you choose one over the other. Except for that, msdn states that
The XDocument class contains the information necessary for a valid XML document. This includes an XML declaration, processing instructions, and comments.
Note that you only have to create XDocument objects if you require the specific functionality provided by the XDocument class. In many circumstances, you can work directly with XElement. Working directly with XElement is a simpler programming model
So I'd stick to XElement, unless any of above mentioned metadata about xml is needed (which doesnt seem to be the case).

Related

Extending Kuali Document Business Object

I am facing an issue with extended attributes on a document (trying to extend a document table). I created the original table’s PK (FDOC_NBR) in the extended table and linked the two via a foreignKey of the customized original table’s ojb entry (as an “extension” reference-descriptor). I created the bo and dd for the extension and customized the original document’s dd to add the new attributes. On the extended BO itself I also added members (with setters and getters) for the 2 new columns + for the PK column of documentNumber. I also added the new attributes to the documet’s jsp. The pertinent module definition was already extended to include custom dd, ojb, etc. files.
Indeed, when opening the document the new fields are shown- however, when trying to submit the document (regardless of doing anything with the new fields) I get an error-
Error Details: OJB operation; SQL []; ORA-01400: cannot insert NULL
into ("KFSTEM"."TEM_TRVL_ARRANGER_DOC_EXT_T"."FDOC_NBR") ; nested
exception is java.sql.SQLIntegrityConstraintViolationException:
ORA-01400: cannot insert NULL into
("KFSTEM"."TEM_TRVL_ARRANGER_DOC_EXT_T"."FDOC_NBR")
Seems like somehow the system tries to insert a value of NULL into the extension’s PK field, instead of the actual document number. Trying to debug this, in the action’s route method and all the way down to DocumentDaoOjb.save (which is as far down as I can go) I see the document with the real doc number is passed on, so the problem seems to be purely with ojb trying to set this number to the extension table.
Does anyone have any experience with extended attributes on documents that could help shed some light on this?
KFS is using the KNS, and in the Kuali Nervous System, the primary key on the extended attributes object must be set through manual intervention.
In this case, it looks as if you're adding an extended attribute to a transactional document, the Travel Arranger document (TAA), which simplifies things. Basically, you'll need to extend org.kuali.kfs.module.tem.document.TravelArrangerDocument and override prepareForSave to set the document number there (it may be set already since prepareForSave should be called several times during the routing process, but there's no real harm from overwriting that information as the base document's number will remain the same).
Hope this helps!

Associating existing Annotation to more than one entity

Say, organisation has an attachment document. Can I associate this attachment to parent organisation via plugin?
I know another annotation can be created for parent record and file attachment can be copied there. But I'd like to avoid storing copies of attached file.
In short, copying is your only option to have the annotation appear in both records.
The way Annotations are designed completely blocks this reasonable possibility. The Annotation "has-a" Object, even though in forms Objects are presented as the parent of Annotation. So we're stuck with the duplication.
You could always write your own microsoft-unsupported schema scripts and a web resource form control... Be sure to share with the community if you do :)

Preventing StackOverflowException while serializing Entity Framework object graph into Json

I want to serialize an Entity Framework Self-Tracking Entities full object graph (parent + children in one to many relationships) into Json.
For serializing I use ServiceStack.JsonSerializer.
This is how my database looks like (for simplicity, I dropped all irrelevant fields):
I fetch a full profile graph in this way:
public Profile GetUserProfile(Guid userID)
{
using (var db = new AcmeEntities())
{
return db.Profiles.Include("ProfileImages").Single(p => p.UserId == userId);
}
}
The problem is that attempting to serialize it:
Profile profile = GetUserProfile(userId);
ServiceStack.JsonSerializer.SerializeToString(profile);
produces a StackOverflowException.
I believe that this is because EF provides an infinite model that screws the serializer up. That is, I can techincally call: profile.ProfileImages[0].Profile.ProfileImages[0].Profile ... and so on.
How can I "flatten" my EF object graph or otherwise prevent ServiceStack.JsonSerializer from running into stack overflow situation?
Note: I don't want to project my object into an anonymous type (like these suggestions) because that would introduce a very long and hard-to-maintain fragment of code).
You have conflicting concerns, the EF model is optimized for storing your data model in an RDBMS, and not for serialization - which is what role having separate DTOs would play. Otherwise your clients will be binded to your Database where every change on your data model has the potential to break your existing service clients.
With that said, the right thing to do would be to maintain separate DTOs that you map to which defines the desired shape (aka wireformat) that you want the models to look like from the outside world.
ServiceStack.Common includes built-in mapping functions (i.e. TranslateTo/PopulateFrom) that simplifies mapping entities to DTOs and vice-versa. Here's an example showing this:
https://groups.google.com/d/msg/servicestack/BF-egdVm3M8/0DXLIeDoVJEJ
The alternative is to decorate the fields you want to serialize on your Data Model with [DataContract] / [DataMember] fields. Any properties not attributed with [DataMember] wont be serialized - so you would use this to hide the cyclical references which are causing the StackOverflowException.
For the sake of my fellow StackOverflowers that get into this question, I'll explain what I eventually did:
In the case I described, you have to use the standard .NET serializer (rather than ServiceStack's): System.Web.Script.Serialization.JavaScriptSerializer. The reason is that you can decorate navigation properties you don't want the serializer to handle in a [ScriptIgnore] attribute.
By the way, you can still use ServiceStack.JsonSerializer for deserializing - it's faster than .NET's and you don't have the StackOverflowException issues I asked this question about.
The other problem is how to get the Self-Tracking Entities to decorate relevant navigation properties with [ScriptIgnore].
Explanation: Without [ScriptIgnore], serializing (using .NET Javascript serializer) will also raise an exception, about circular
references (similar to the issue that raises StackOverflowException in
ServiceStack). We need to eliminate the circularity, and this is done
using [ScriptIgnore].
So I edited the .TT file that came with ADO.NET Self-Tracking Entity Generator Template and set it to contain [ScriptIgnore] in relevant places (if someone will want the code diff, write me a comment). Some say that it's a bad practice to edit these "external", not-meant-to-be-edited files, but heck - it solves the problem, and it's the only way that doesn't force me to re-architect my whole application (use POCOs instead of STEs, use DTOs for everything etc.)
#mythz: I don't absolutely agree with your argue about using DTOs - see me comments to your answer. I really appreciate your enormous efforts building ServiceStack (all of the modules!) and making it free to use and open-source. I just encourage you to either respect [ScriptIgnore] attribute in your text serializers or come up with an attribute of yours. Else, even if one actually can use DTOs, they can't add navigation properties from a child object back to a parent one because they'll get a StackOverflowException.
I do mark your answer as "accepted" because after all, it helped me finding my way in this issue.
Be sure to Detach entity from ObjectContext before Serializing it.
I also used Newton JsonSerializer.
JsonConvert.SerializeObject(EntityObject, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });

Help to restructure my Doc/View more correctly

Edited by OP.
My program is in need of a lot of cleanup and restructuring.
In another post I asked about leaving the MFC DocView framework and going to the WinProc & Message Loop way (what is that called for short?). Well at present I am thinking that I should clean up what I have in Doc View and perhaps later convert to non-MFC it that even makes sense. My Document class currently has almost nothing useful in it.
I think a place to start is the InitInstance() function (posted below).
In this part:
POSITION pos=pDocTemplate->GetFirstDocPosition();
CLCWDoc *pDoc=(CLCWDoc *)pDocTemplate->GetNextDoc(pos);
ASSERT_VALID(pDoc);
POSITION vpos=pDoc->GetFirstViewPosition();
CChildView *pCV=(CChildView *)pDoc->GetNextView(vpos);
This seem strange to me. I only have one doc and one view. I feel like I am going about it backwards with GetNextDoc() and GetNextView(). To try to use a silly analogy; it's like I have a book in my hand but I have to look up in it's index to find out what page the Title of the book is on. I'm tired of feeling embarrassed about my code. I either need correction or reassurance, or both. :)
Also, all the miscellaneous items are in no particular order. I would like to rearrange them into an order that may be more standard, structured or straightforward.
ALL suggestions welcome!
BOOL CLCWApp::InitInstance()
{
InitCommonControls();
if(!AfxOleInit())
return FALSE;
// Initialize the Toolbar dll. (Toolbar code by Nikolay Denisov.)
InitGuiLibDLL(); // NOTE: insert GuiLib.dll into the resource chain
SetRegistryKey(_T("Real Name Removed"));
// Register document templates
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CLCWDoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CChildView));
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCmdLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
// The window frame appears on the screen in here.
if (!ProcessShellCommand(cmdInfo))
{
AfxMessageBox("Failure processing Command Line");
return FALSE;
}
POSITION pos=pDocTemplate->GetFirstDocPosition();
CLCWDoc *pDoc=(CLCWDoc *)pDocTemplate->GetNextDoc(pos);
ASSERT_VALID(pDoc);
POSITION vpos=pDoc->GetFirstViewPosition();
CChildView *pCV=(CChildView *)pDoc->GetNextView(vpos);
if(!cmdInfo.m_Fn1.IsEmpty() && !cmdInfo.m_Fn2.IsEmpty())
{
pCV->OpenF1(cmdInfo.m_Fn1);
pCV->OpenF2(cmdInfo.m_Fn2);
pCV->DoCompare(); // Sends a paint message when complete
}
// enable file manager drag/drop and DDE Execute open
m_pMainWnd->DragAcceptFiles(TRUE);
m_pMainWnd->ShowWindow(SW_SHOWNORMAL);
m_pMainWnd->UpdateWindow(); // paints the window background
pCV->bDoSize=true; //Prevent a dozen useless size calculations
return TRUE;
}
Thanks
Hard to give you good recommendations without knowing what your program shall do. I have only a few general remarks:
Your InitInstance does not look very messed up for me. It's pretty much standard with a bit of custom code in it.
Also the ugly construction to retrieve the first view from the application class (the chain GetDocTemplate -> GetDoc -> GetView) is standard to my knowledge. I actually don't know another way. You might think about moving it into a separate method like CChildView* CLCWApp::GetFirstView() but well, that's only cosmetic as long as you need it only at one place.
What you are doing and which data you are placing in your Document class and in your View class(es) is more a semantic question if you only have one view. (You have only one document anyway because it's an SDI application.). From a technical viewpoint often both is possible.
But to be open for (perhaps) later extensions to more than one view and to follow the standard pattern of a doc/view architecture there are a few rules of thumb:
Data which exist and have a meaning independent of the way to present and view them (a document file, a database handle, etc.) belong to the document class. I don't know what your pCV->OpenF1(cmdInfo.m_Fn1) ... and so on does but if it's something like a file or filename or a parameter to be used to access data in any way OpenF1 might be better a method of the document class.
Methods which do any kind of data processing or modification of your underlying data belong to the document class as well
Data and methods which are only needed for a specific way to display a document belong to a view class (for instance a selected font, colours, etc.)
On the other side: If you have a fixed number of views which open with the document it might not be wrong to put view specific data into the document, especially if you want to make those view parameters persistent. An example would be a file with some statistical data - your document - and a splitter frame with two views: one displays the data as a grid table and the other as a pie chart. The table has "view data" describing the order of and width of columns, the pie chart has data to configure the colours of the pie pieces and the legend location, for instance. If you want to make sure that the user gets the last view configuration displayed when he opens the document file you have to store these view parameters somewhere. It wouldn't be wrong or bad design in my opinion to store those parameters in the document too, to store and retrieve them from any permanent storage, even if you need them only in the view classes.
If your application allows to open an unlimited number of views for a document dynamically and those views are only temporary as long as the application runs, storing all view configuration parameters directly in the view classes seems more natural to me. Otherwise in the document you would need to manage any kind of dynamic data structure and establish a relationship between a View and an entry in this data structure (an index in an array, or a key in a map, etc.)
If you are in doubt whether to place any data in the document or view class I'd prefer the document because you always have the easy GetDocument() accessor in the View class to retrieve members or call methods of the Doc. To fetch data from the View into the Document requires to iterate through the list of views. (Remember: Doc-View is a 1-n relationship, even in a SDI application.)
Just a few cents.

Can you use key/keyref instead of restriction/enumeration in XML schema?

Suppose we have a stylesheet which pulls in metadata using the key() function. In other words we have instance documents like this:
<items>
<item type="some_type"/>
<item type="another_type"/>
</items>
and a table of additional data we would like to associate with items during processing:
<item-meta>
<item type="some_type" meta="foo"/>
<item type="another_type" meta="bar"/>
<item type="yet_another_type" meta="baz"/>
</item-meta>
Finally, suppose we want to do schema validation on the instance document, restricting the type attributes to the set of types which occur in item-meta. So in the schema we want to use key/keyref instead of restriction/enumeration. This is because using restriction/enumeration will require making a separate list of valid type attributes.
However, it doesn't look like key/keyref will actually work. Having tried it (with MSXML 6.0) it appears the selector of a schema key won't accept the document() function in its xpath argument, so we can't examine the item-meta data, whether it appears in an external file or in the schema file itself. It looks like the only place we can look for keys is the instance document.
So if we really don't want to have a separate list of valid types, we have to do a pre-validation transform, pulling in the item-meta stuff, then do the validation, then do our original transform. That seems overcomplicated for what ought to be a relatively straightforward use of XML schema and stylesheets.
Is there a better way?
Selectors in key/keyref allow only a very restricted xpath syntax. Short, but not completely accurate: The selector must point to a subnode of the element declared.
The full definition of the restricted syntax is -> here.
So, no I don't see a better way, sorry.
BTW: The W3C states that this restriction was made to make life easier on implementers of XML Schema processors. Keep in mind that one of the design goals of XML Schema was to make it possible to process a document in streaming mode. That explains really a lot of the sometimes seemingly random restrictions of XML Schema.
Having thought about it a little more, I came up with the idea of having the stylesheet do that part of the validation. The schema would define the item type as a plain string, and the stylesheet would emit a message and stop processing if it couldn't look up the item type in the item-meta table.
This solution fixes the original problem of having to write down the list of valid types more than once, but it introduces the problem that validation logic is now mixed in with the stylesheet logic. I don't have enough experience with XSD+XSLT to tell whether this new problem is less serious than the old one, but it seems to be more elegant than what I wrote earlier about pulling the item-meta table into each instance document in a pre-validation transform.
You wouldn't need to stop the XSLT with some error. Just let it produce something that the schema won't validate and that points to the original problem like
<error txt="Invalid-Item-Type 'invalid_type'"/>
Apart from that please keep in mind that there are no discussion threads here. The posts may go up and down, so it's better to edit your question accordingly.
Remember, the philosophy here is "One question, and the best answer wins".

Resources