C++ Windows Forms Application - XML edit existing xml child node - c++

I have some problems with editing existing child node, I don't know if its possible but I hope it is. I tried almost everything.
This is part of code that I use to retrieve first childnode text
int x;
void ReadX()
{
String ^ strFilename = L"test.xml";
XmlDocument ^ testxml = gcnew XmlDocument;
if (File::Exists(strFilename))
{
testxml->Load(strFilename);
XmlElement ^ elm = testxml->DocumentElement;
XmlNodeList ^ lstVideos = elm->ChildNodes;
//MessageBox::Show(elm->Name);
//MessageBox::Show(elm->InnerText);
x = Convert::ToInt32(lstVideos[0]->InnerText);
}
and on button click
textBox1->Text=System::Convert::ToString(x);
What i would like to do is on button2 click to input value from textBox1 to lstVideos[0]->InnerText
Please don't link me msdn because I already worked with their examples, and I didn't manage to solve it.
I still have to learn a lot about xml, what it would to is edit text of X1, my code above reads X1's text. Would probably be easier to read childnode by name, but I don't yet know how to do that.
This is my xml file
<?xml version="1.0" encoding="utf-8"?>
<Coords>
<X1>10010</X1>
<X2>200</X2>
<X3>300</X3>
<X4>400</X4>
<X5>500</X5>
</Coords>

Since InnerText is a String^ and textBox1->Text is a String^, why not:
lstVideos[0]->InnerText = textBox1->Text
Also, since both are strings, there is really no reason to convert the InnerText to an int, then back in the first place.

Related

How to Create a Child with pair tag with QT

I am working on a project where I have to write information in a XML document using QT Library ( QTDomDocument, etc.) for C++.
It might be stupid to ask, but I am looking for a solution on how to create a XML child node with pair tags, for example, I have this :
<color_space>
</color_space>
And I would like to add x childs following this schema:
<color_space>
<color_plan>R</color_plan>
<color_plan>G</color_plan>
...
</color_space>
I have tried multiple different codes and as far I did, the most similar resultat that I had was :
<color_space>
<color_plan/>
<color_plan/>
...
</color_space>
Thank you all for your help.
Ok so I Just Figured out how to do what I attempted to do, I hope it will help other people!
// Here we have a QVector where we have all our color plan
QVector<QString>ColorPlanTable= { "R","G","B","L","a","b","Y","Cb","Cr" };
//sub_element is the Color_space element (parent node)
sub_element= sub_element.nextSiblingElement();
// Here we create a new element for color_plan (child of Color_space)
QDomElement NewColorPlan=document_->createElement("color_plan");
// And then we create a TextNode to add to the element color_plan
QDomText NewColorPlanText = document_->createTextNode(ColorPlanTable.at(i));
// Adding the element color_plan as a child of Color_space
sub_element.appendChild(NewColorPlan);
// And then adding the text of the color_plan!
NewColorPlan.appendChild(NewColorPlanText);

XML Name space issue revisited

XML Name space issue revisited:
I am still not able to find a good solution to the problem that the findnode or findvalue does not work when we have xmlns has some value.
The moment I set manually xmlns="", it starts working. At least in my case. Now I need to automate this.
consider this
< root xmlns="something" >
--
---
< /root>
My recommended solution :
dynamically set the value to xmlns=""
and when the work is done automatically we can reset to the original value xmlns="something"
And this seems to be a working solution for my XMLs only but its stll manual.
I need to automate this:
How to do it 2 options:
using Perl regex, or
using proper LibXML setNamespace etc.
Please put your thought in this context.
You register the namespace. The point of XML is not having to kludge around with regexes!
Besides, it's easier: you create an XML::LibXML::XPathContext, register your namespaces, and use its find* calls with your chosen prefixes.
The following example is verbatim from a script of mine to list references in Visual Studio projects:
(...)
# namespace handling, see the XML::LibXML::Node documentation
my $xpc = new XML::LibXML::XPathContext;
$xpc->registerNs( 'msb',
'http://schemas.microsoft.com/developer/msbuild/2003' );
(...)
my $tree; eval { $tree = $parser->parse_file($projfile) };
(...)
my $root = $tree->getDocumentElement;
(...)
foreach my $attr ( find( '//msb:*/#Include', $root ) )
{
(...)
}
(...)
sub find { $xpc->find(#_)->get_nodelist; }
(...)
That's all it takes!
I only have one xmlns attribuite at the top of the XML once only so this works for me.
All I did was first to remove the namespace part i.e. remove the xmlns from my XML file.
NODE : for my $node ($conn->findnodes("//*[name()='root']")) {
my $att = $node->getAttribute('xmlns');
$node->setAttribute('xmlns', "");
last NODE;
}
using last just to make sure i come of the for loop in time.
And then once I am done with the XML parsing I will replace the
<root>
with
<root xmlns="something">
using simple Perl file operation or sed editor.

Word automation with C++ Builder 5

I'm trying to control Word through a c++ builder 5 application. I would like to
open a ".dot" model file created with Word and modify it. In the ".dot" model file
there are some fields. For example, Title, LastName, FirstName, Address
and so on, and I would like to modify these fields putting text into them and then
saving file with a new name, for example "Warning.doc" leaving the ".dot" file
unaltered.
I can open the file, count the number of fields it contains, but then
when it comes to replacing each field with a string I don't know how to do because
I don't have a complete documentation on OleFunction and OlePropertyGet methods. I attach my source code to this message, can anybody help me to solve this problem please?
try
{
my_word = Variant::CreateObject("word.application");
}
catch (...)
{
Application->MessageBox("Unable to obtain Word automation object",
"Error:",MB_OK | MB_ICONERROR);
}
my_word.OlePropertySet("Visible", (Variant)true);
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Variant this_doc;
Variant my_fields;
Variant test;
int k,field_count;
AnsiString test1;
AnsiString filename = "d:\\ProgrammaWord\\1-Avviso.dot";
my_docs = my_word.OlePropertyGet("Documents");
this_doc = my_docs.OleFunction("Open", filename);
my_fields = this_doc.OlePropertyGet("Fields");
field_count = my_fields.OlePropertyGet("Count");
for(k = 1; k <= field_count; k++)
{
test = my_fields.OleFunction("Item",(Variant)k);
test1 = test.OleFunction("Value"); //This instruction throws an exception
// "Value" is not a recognized parameter
// in this case
Memo1->Lines->Add(test1);
}
}
I never used word Ole but I used it for Outlook and Excel, I can't try it with word since I'm currently on OSX but you should try something similar as what I did.
The generic way of using Ole was to OleGetproperty() while you get the targeted field then OleSetProperty("action", ...).
for example when I wanted to change the color of the text in a particular cell of my excel document I used:
Variant _excel = Variant::CreateObject("Excel.Application");
Variant _workbook = _excel.OlePropertyGet("WorkBooks").OleFunction("Open", filename);
Variant _worksheet = _workbook.OlePropertyGet("WorkSheets", sheet);
_worksheet.OlePropertyGet("Cells", row, col).OlePropertyGet("Font").OlePropertySet("Color", color);
Here I instanciate an excel object, then I load a file into it (_workbook), then I select the _worksheet from the _workbook and I start my business.
Here comes the interesting part:
It concist of getting to a particular cell, getting the font object from it, and then setting the color of this font object.
Disclaimer: This is an example from my sources for excel, it's not directly related to your example, but maybe you can understand the principe with it. I can't try to figure out what you need because I have no windows right now.
Hope this can help you. Finding ressources for OLE can be fierce if you don't have the good patterns to look for.

How to replace text in content control after, XML binding using docx4j

I am using docx4j 2.8.1 with Content Controls in my .docx file. I can replace the CustomXML part by injecting my own XML and then calling BindingHandler.applyBindings after supplying the input XML. I can add a token in my XML such as ¶ then I would like to replace that token in the MainDocumentPart, but using that approach, when I iterate through the content in the MainDocumentPart with this (link) method none of my text from my XML is even in the collection extracted from the MainDocumentPart. I am thinking that even after binding the XML, it remains separate from the MainDocumentPart (??)
I haven't tried this with anything more than a little test doc yet. My token is the Pilcrow: ¶. Since it's a single character, it won't be split in separate runs. My code is:
private void injectXml (WordprocessingMLPackage wordMLPackage) throws JAXBException {
MainDocumentPart part = wordMLPackage.getMainDocumentPart();
String xml = XmlUtils.marshaltoString(part.getJaxbElement(), true);
xml = xml.replaceAll("¶", "</w:t><w:br/><w:t>");
Object obj = XmlUtils.unmarshalString(xml);
part.setJaxbElement((Document) obj);
}
The pilcrow character comes from the XML and is injected by applying the XML bindings to the content controls. The problem is that the content from the XML does not seem to be in the MainDocumentPart so the replace doesn't work.
(Using docx4j 2.8.1)

Writing XML strips trailing spaces

I am trying to write an XML file using MSXML4. It works fine except when I have a data element with a trailing space which must be preserved.
Given the following code to insert a new element:
const _bstr_t k_Parent (ToBSTR("ParentNode"));
const _bstr_t k_Child (ToBSTR("ChildNode"));
const _bstr_t k_Data (ToBSTR("DataWithTrailingSpace "));
const _bstr_t k_Namespace (ToBSTR("TheNameSpace"));
MSXML2::IXMLDOMDocument2Ptr m_pXmlDoc;
m_pXmlDoc->async = VARIANT_FALSE;
m_pXmlDoc->validateOnParse = VARIANT_FALSE;
m_pXmlDoc->resolveExternals = VARIANT_FALSE;
m_pXmlDoc->preserveWhiteSpace = VARIANT_TRUE;
MSXML2::IXMLDOMNodePtr pElement = m_pXmlDoc->createNode(NODE_ELEMENT, k_Child, k_Namespace);
MSXML2::IXMLDOMNodePtr pParent = m_pXmlDoc->selectSingleNode(k_Parent);
pElement->put_text (k_Data);
MSXML2::IXMLDOMNodePtr pNewChild = pParent->appendChild(pElement);
If I check "pNewChild->text", the text still contains the trailing space. When I try writing it to a file:
std::string xml (static_cast<std::string>(m_pXmlDoc->xml));
std::ofstream file("output.xml");
file << xml << std::endl;
file.flush();
file.close();
The output is:
<ParentNode>
<ChildNode>DataWithTrailingSpace</ChildNode>
</ParentNode>
Instead of (note the extra space behind "DataWithTrailingSpace"):
<ParentNode>
<ChildNode>DataWithTrailingSpace </ChildNode>
</ParentNode>
I cannot figure out at what point the trailing space is getting stripped.
Can someone please provide some insights in to where this may be occurring and how I can correct it?
If you need to preserve whitespace then you should be using a CDATA section via createCDATASection() or the like.
Mystery solved. Don't preview your XML in Internet Explorer. It hides trailing spaces. Use notepad instead.
You should replace the whitespace(s) with  . That way your whitespaces should persist.
EDIT
Appearantly it didn't solve your problem. Then maybe you want to have a look at these sites:
http://msdn.microsoft.com/en-us/library/ms757008(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms757885(VS.85).aspx