Rich Text content control data binding with docx4j - docx4j

Trying to create a data binding to custom XML part for a sdtBlock representing a rich text content control is not working because it creates a w:dataBinding tag in the resulting XML instead of a w15:dataBinding. Rich text content control require a w15 namespace uri.
I am creating the data binding directly in Java, not in an authoring tool, with this code:
org.docx4j.wml.CTDataBinding cTDataBinding = new CTDataBinding();
And there is no data binding class in org.docx4j.w15 package.
Is there any way to specify that a different namespace should be used for this instance when marshalling?

https://github.com/plutext/docx4j/blob/master/docx4j-openxml-objects/src/main/java/org/docx4j/w15/ObjectFactory.java#L232 contains:
#XmlElementDecl(namespace = "http://schemas.microsoft.com/office/word/2012/wordml", name = "dataBinding")
public JAXBElement<CTDataBinding> createDataBinding(CTDataBinding value) {
return new JAXBElement<CTDataBinding>(_DataBinding_QNAME, CTDataBinding.class, null, value);
}
so you should be able to create what you want using the w15 ObjectFactory. For example:
SdtPr sdtPr = new SdtPr();
JAXBElement<CTDataBinding> w15DataBinding = new org.docx4j.w15.ObjectFactory().createDataBinding(new CTDataBinding());
sdtPr.getRPrOrAliasOrLock().add(w15DataBinding);
System.out.println(XmlUtils.marshaltoString(sdtPr));
produces (omitting some namespaces):
<w:sdtPr xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" >
<w15:dataBinding/>
</w:sdtPr>

Related

Hybris DataHub INVALID_LOCALE Exception

I have localized raw data item baseName. I want to send localized raw data item to DataHub. I read many documents, it writes send localized raw attribute value but I couldn't find the format of the localized attribute value. In the composition, it throws INVALID_LOCALE exception.
I am sending value for baseName, but how can I localized "XYZ"?
RawFragmentData rawFragmentData = new RawFragmentData();
final Map<String, String> line = new HashMap<>();
........
line.put("baseName", "XYZ");
........
rawFragmentData.setValueMap(line);
rawFragmentData.setType(type);
rawFragmentData.setDataFeedName(feedName);
rawFragmentData.setExtensionSource(Constants.DATAHUB_EXTENSION_SOURCE);
return rawFragmentData;
e.g OOTB :
DefaultPartnerContributor.Java :-
row.put(PartnerCsvColumns.COUNTRY_ISO_CODE, address.getCountry());
Same way you might have languageColumn for it, so just pass language value to it.

Binding IEnumerable<anonymous object> to DataGrid in WPF

I need merely a readonly display of Linq data; no requirement to observe changes. Here's the Linq:
string ZIPCODEFIELDNAME="zip5";
DataTable DATA = (detailedQueryResult as DataTable);
IEnumerable<object> ZIPCODE_SUMMARY;
ZIPCODE_SUMMARY = from z in DATA.AsEnumerable()
group z by z.Field<string>(ZIPCODEFIELDNAME) into g
let list = g.ToList()
select new
{
zip = g.Key,
eecount = list.Count(),
// possible additional aggregate columns here
};
I am able to bind this IEnumerable<anonymous object> to a Telerik RadGridView in code-behind simply by doing this:
myRadGridView.ItemsSource = ZIPCODE_SUMMARY.ToList();
that is, without having to declare a binding in XAML or having to define any columns. How would that be accomplished using the WPF DataGrid that ships with Visual Studio? It displays only row separators when I use the identical approach. So it knows about the items in the list, just not how to fetch the columns.
I am trying to write some quick-and-dirty utilities to import a gazillion CSV files where no two of them have the same structure or same field names, and the fewer lines of setup code the better.
P.S. I am just getting into WPF and Linq, so please set ReplyToNovice=true :-)
Did you remember to set AutoGenerateColumns=true on the datagrid? If yes, try binding to an ICollectionView instead.
UPDATE:
Thats weird, the code below works fine for me. One thing though, you may have to set the datacontext of the datagrid to {Binding}, this will bind to the whole object.
public MainWindow()
{
InitializeComponent();
dgZips.ItemsSource = GetFakeZips();
}
public dynamic GetFakeZips()
{
return Enumerable.Range(1500, 10).Select(i => new { Zip = i, Count = i / 4 });
}
Xaml:
<DataGrid x:Name="dgZips" AutoGenerateColumns="True" />

Creating new smartform data using Ektron ContentTypes

Ektron 8.0.1 SP1
I am using SmartForms and Content Types to read (and hopefully write) data. I can read data but now I am attempting to write a new record similar to the following.
ContentTypeManager<member> contentTypeManager = new ContentTypeManager<member>();
ContentType<member> newmem = new ContentType<member>();
newmem.SmartForm.details.field1 = "Chuck"; // This line throws 'Object reference not set to an instance of an object.' error
newmem.SmartForm.details.field2 = "Norris";
contentTypeManager.Update(newmem);
I get the error "Object reference not set to an instance of an object." for that first assignment line. What am I missing?
I am having trouble finding good documentation on ContentTypes for 8.0.1 now that the Ektron website has been redesigned.
Thx.
Thanks for clarifying, to ADD content to a folder that has a smartform assigned to it, the basic code block should get you started: (Note: the Html attribute of the content is simply the xml matched to the schema you created)
Ektron.Cms.Framework.Content.ContentManager cmanager = new Cms.Framework.Content.ContentManager();
Ektron.Cms.ContentData cdata = new ContentData();
cdata.FolderId = 0;
cdata.XmlConfiguration.Id = 0; //SMARTFORM ID HERE
cdata.Html = "<root><field1>field1 value</field1><field2>field2 value</field2></root>";
cmanager.Add(cdata);
You could update ContentTypes.cs to include an Add method. Just copy the Update method and change contentManager.Update to contentManager.Add.
public void Add(ContentType<T> contentType)
{
Initialize();
contentType.Content.Html = Ektron.Cms.EkXml.Serialize(typeof(T), contentType.SmartForm);
contentManager.Add(contentType.Content);
}
Unfortunately, contentManager.Add returns void. Ideally it should return the new content ID.

Problem saving a new item to custom SharePoint 2007 list using Silverlight 4 UI control

I am hoping someone might be able to help me. I'm working on a Contact Manager built using a custom SharePoint 2007 list with a Silverlight 4 UI embedded in a content editor web part.
I am currently able to retrieve the data from the list and display it in a datagrid on the UI and everything works well.
Now I am trying to add the the ability to add new items to the list using the following code but the items do not save.
I've remotely debugged the following code using the Debug -> Attach to Process option and everything seems to execute successful without any errors but it does not save the item to SharePoint.
In order to simplify and get a working insert function I changed all the SharePoint fieds to single line text with the exception of the notes (multiline) and none of the fileds are required.
The sharepoint site does require Windows authentication but it seems to be working correctly as I am able to display it as well as add new items manually using the standard SharePoint forms.
Lastly, I have added the xml for the Batch element at the bottom which I copied as output while debuging.
Please let me know if there is any additional information I might be missing.
Thanks in advance for any assistance you might be willing to provide.
Charles
public string sharepoint_soap_namespace = "http://schemas.microsoft.com/sharepoint/soap/";
public string sharepoint_rowset_namespace = "#RowsetSchema";
public string service_lists_url = "http://myDomain/_vti_bin/lists.asmx";
public string listName = "MyContacts";
public void TestCreateContact()
{
Uri serviceUri = new Uri(service_lists_url);
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
binding.MaxReceivedMessageSize = 2147483647; // This has to be the same as in the ServiceReferences.ClientConfig file.
EndpointAddress endpoint = new EndpointAddress(serviceUri);
ListsSoapClient testCreateClient = new ListsSoapClient(binding, endpoint);
XElement batch = new XElement("batch",
new XElement("Method",
new XAttribute("ID", "1"),
new XAttribute("Cmd", "New"),
CreateFieldElement("ows_ID", "New"),
CreateFieldElement("ows_Title", "John"),
CreateFieldElement("ows_SupportFor","USA"),
CreateFieldElement("ows_LastName","Doe")
));
testCreateClient.UpdateListItemsCompleted +=
new EventHandler<UpdateListItemsCompletedEventArgs>(createSoapClient_UpdateListItemsCompletedEventArgs);
testCreateClient.UpdateListItemsAsync(listName, batch);
testCreateClient.CloseAsync();
}
private XElement CreateFieldElement(string fieldName, string fieldValue)
{
XElement element = new XElement("Field",
new XAttribute("Name", fieldName),
fieldValue);
return element;
}
Just a quick update to let everyone know I was able to answer my own question.
It seems that in the batch XElement I was using the wrong field names.
CreateFieldElement("ows_SupportFor","USA"),
I was using "ows_SupportFor" instead of "SupportFor" without the "ows_" prefix.
Cheers,
Charles

Problem with generating XPS documents with images in a WCF class library

I have a Silverlight application which uses a web service in order to create XPS documents. The document templates are created as XAML controls in a WCF class library.
public void GenerateXPS()
{
Type typeofControl = Type.GetType(DOCUMENT_GENERATOR_NAMESPACE + "." + ControlTypeName, true);
FrameworkElement control = (FrameworkElement)(Activator.CreateInstance(typeofControl));
control.DataContext = DataContext;
FixedDocument fixedDoc = new FixedDocument();
PageContent pageContent = new PageContent();
FixedPage fixedPage = new FixedPage();
//Create first page of document
fixedPage.Children.Add(control);
((IAddChild)pageContent).AddChild(fixedPage);
fixedDoc.Pages.Add(pageContent);
XpsDocument xpsd = new XpsDocument(OutputFilePath + "\\" + OutputFileName, FileAccess.ReadWrite);
System.Windows.Xps.XpsDocumentWriter xw = XpsDocument.CreateXpsDocumentWriter(xpsd);
xw.Write(fixedDoc);
xpsd.Close();
SaveToDocumentRepository();
}
In order to bind the actual data to my document template I set the DataContext property of the control. The problem is that when I look at my XPS, the images (I bind the Source of my Image controls to a string property that represents the URL of my image) are not displayed as if they were not loaded. How can I solve this problem? Thanks!
The binding infrastructure probably needs a push along because you are operating outside the intended use of WPF.
Try adding the following code after setting the datacontext:
control.DataContext = DataContext;
// we need to give the binding infrastructure a push as we
// are operating outside of the intended use of WPF
var dispatcher = Dispatcher.CurrentDispatcher;
dispatcher.Invoke(
DispatcherPriority.SystemIdle,
new DispatcherOperationCallback(delegate { return null; }),
null);
I cover this and other XPS related stuff in this blog post.