QL.túra

Kulturális smörgåsbord Esterházytól Wass Albertig, a gumicsizmától az iPad-ig, a Teletabiktól Sexpírig, a makrofágtól a mikrokontrollerig, miazmás...

Címkék

2000 (20) 2001 (6) 2002 (16) 2003 (164) 2004 (61) 2005 (40) 2006 (31) 2007 (28) 2008 (33) 2009 (175) 2010 (188) 2011 (201) 2012 (86) 2013 (40) 2014 (36) 2015 (26) 2016 (10) adáshiba (91) android (1) animáció (93) cygwin (3) film (410) gezarol (13) hájtek (159) hangoskönyv (32) ipad (17) klip (12) könyv (191) linux (29) színház (169) vers (17) windows (37) zene (111) Címkefelhő

+jegyzések

Most ...

... múlok .osan

bmi_tiny.png


... hallgatom
Szabó Magda: Régimódi történet
https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSqTmZEqlCRFgojyt52Q2n_qiMTyVlt-zJu-DpbNKVY6OQbBh4u


... olvasom
Alexander Steele (szerk.): Kezdő írók kézikönyve


... (Kik ezek? Kik ezek az embek? Kik ezek?)
profile for TrueY on Stack Exchange, a network of free, community-driven Q&A sites
free counters

[Hájtek] Formázott XML output MSXML 4.0-val

2012.10.02. 11:00 | TrueY | Szólj hozzá!

Címkék: windows 2012 hájtek

Tegyük fel, hogy C++-ban szeretnénk XML file-t gyártani. Ehhez kedvenc Microsoft-unk mellékeli az MSXML könyvtárat. Sajna az MSXML save függvénye egyetlen sorban írja ki az XML-t. Ez eléggé olvashatatlanná silányítja a terméket. 4.0-ás MSXML-lel kellett ezt valami értelmes módon megoldanom.

Gugliztam egy kicsit és találtam egy megoldást >itt<. Én botor módon azt hittem, hogy kb. egy utasítással meg lehet oldani, de nem! A fél kalevalát be kell kopipasztázni!

A végén meg át is kellett alakítanom, mert sehogy sem sikerült file-ba masszíroznom az eredményt. Sajnos sok a nem dokumentált történés, de végül sikerült és azóta boldogan használom. Remélem másoknak is segít ez a kis szösszenet.

Először is nézzük a szükséges fejlécelést és globális ügymenetet. VS2010 alatt fordítva műxik.

#include "msxml2.h"
#include <iostream>
#include <fstream>
...
MSXML2::IXMLDOMDocument2Ptr pDoc;
...
#define ifCOMFailed(ret) if (FAILED(hr = ret)) { \
::MessageBox(NULL, _com_error(hr).ErrorMessage(), _T("Error"), MB_OK); \
return 0; }

A pDoc-ba az XML fa kerül bele. Az ifCOMFailed macro csak egy kis kódrövidítés (bocs érte!). Az ez után levők egy függvénybe foglalandó, hogy a macro return 0-ja érvényesülni tudjon... A kód első fele egy UTF-16 kódolású variant string-be szuszakolja a beformázott anyagot. Bevallom, hogy nem értem, hogy mit csinál, de működik!
// MXWriter létrehoz
CComPtr <IMXWriter> pMXWriter;
ifCOMFailed(pMXWriter.CoCreateInstance(__uuidof (MXXMLWriter),
NULL, CLSCTX_ALL));
CComPtr <ISAXContentHandler> pISAXContentHandler;
ifCOMFailed(pMXWriter.QueryInterface(&pISAXContentHandler));

CComPtr <ISAXErrorHandler> pISAXErrorHandler;
ifCOMFailed(pMXWriter.QueryInterface(&pISAXErrorHandler));

CComPtr <ISAXDTDHandler> pISAXDTDHandler;
ifCOMFailed(pMXWriter.QueryInterface(&pISAXDTDHandler));

ifCOMFailed(pMXWriter->put_indent(VARIANT_TRUE));
// Encoding-ot nem használja az IMXWriter, ha BSTR a kimenet.
// UTF-16-ot ír be helyette.
//ifCOMFailed(pMXWriter->put_encoding(L"utf-8"));
VARIANT output;
output.vt = VT_EMPTY; // Default: BSTR output
ifCOMFailed(pMXWriter->put_output(output));

// SAX reader létrehoz
CComPtr <ISAXXMLReader> pSAXReader;
ifCOMFailed(pSAXReader.CoCreateInstance(__uuidof(SAXXMLReader),
NULL, CLSCTX_ALL));

ifCOMFailed(pSAXReader->putContentHandler(pISAXContentHandler));
ifCOMFailed(pSAXReader->putDTDHandler(pISAXDTDHandler));
ifCOMFailed(pSAXReader->putErrorHandler(pISAXErrorHandler));
ifCOMFailed(pSAXReader->putProperty(L"http://xml.org/sax/properties/lexical-handler", CComVariant (pMXWriter)));
ifCOMFailed(pSAXReader->putProperty(L"http://xml.org/sax/properties/declaration-handler", CComVariant (pMXWriter)));

// Kiír
ifCOMFailed(pSAXReader->parse(CComVariant(&*pDoc)));
ifCOMFailed(pMXWriter->get_output(&output));

Sajnos pár dolgot át kell alakítani. Tab-okat használ, ezeket 2 szóközre cseréltem. A több soros commenteket több egysoros commentre cseréli. Nem értem, hogy miért!

CString s = (LPCTSTR)output.bstrVal;
s.Replace(_T("\t"), _T(" ")); // tab túl széles. Legyen 2 szóköz
s.Replace(_T("-->\r\n<!--"), _T(" ")); // Comment sorok széttörve
s += _T("\r\n"); // Üres sorvég hozzáad
Most már csak ki kellene írni. Ha így hagyjuk, akkor az UTL-16 BOM-ot elé írva már ki is írhatjuk, de én inkább UTF-8-ban szeretném. Ehhez még egy pici masszírozni kell a kódot.

s.Replace(_T("\"UTF-16\""), _T("\"UTF-8\""));
string buffer = CT2CA(s, CP_UTF8);
try {
     ofstream xml_out(flName, ios_base::out | ios_base::trunc | ios_base::binary);
     xml_out << buffer;
     xml_out.close();
} catch(const exception &e) {
     ::MessageBox(NULL, CString(e.what()), _T("Save Error"), MB_OK);
     return 0;
}

Ez végre egy szépen beformázott file-t hoz létre.

Formázódjunk minden nap!

A bejegyzés trackback címe:

https://qltura.blog.hu/api/trackback/id/tr664171043

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása