MSXML - сохранение с отступами - 1
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 09.07.02 04:41
Оценка: 17 (3)
#Имя: FAQ.xml.indent1
Здравствуйте Slayer, Вы писали:

O$>>Можно ли заставить MSXML парсер сохранять документы в структурированном виде? У меня шарошит весь файл в одну строку

S>Не раз уже такой вопрос возникал — и ни разу я ответа не видел . Нельзя вроде бы это сделать с помощью парсера... Ручками надобно чего-нить дописывать...


спасибо Илье, подсказал еще одну штуку — http://groups.google.ca/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=38F675F48B36D4118E4D00508B5EBA3761554A%40cpmsftmsgv21.microsoft.com&rnum=1&prev=/groups%3Fq%3DMSXML%2Bsave%2BCR%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3D38F675F48B36D4118E4D00508B5EBA3761554A%2540cpmsftmsgv21.microsoft.com%26rnum%3D1
действительно то что дохтур прописал, на VB выглядит вообще смешно


    'oXML - IXMLDOMDocument
    'sXML - строка
    sXML = oXML.XML
    oXML.loadXML(Replace(sXML, "><", ">" & vbCrLf & "<"))


на C++ строк поболее, но смысл тот же, надругаться перед сохранением:

        CComBSTR bstrXML( L"" );
        hr = spDomDocument->get_xml( &bstrXML ); // CComPtr<IXMLDOMDocument> spDomDocument;

        // вставляем переводы строки
        CString sXml = W2A( bstrXML );
        sXml.Replace( "><", ">\n<" );
        bstrXML = sXml.GetBuffer( 0 );

        // загружаем взад
        hr = spDomDocument->loadXML( bstrXML, &bSuccess );

        // сохраняем файлы
        hr = spDomDocument->save( CComVariant( L"file.xml") );


получается чудненько структурированный документ со всеми отступами.
Re[5]: MSXML
От: ak_alex Россия  
Дата: 22.08.02 09:55
Оценка: 18 (1)
Здравствуйте Odi$$ey, Вы писали:

O$>Здравствуйте ak_alex, Вы писали:


O$>а можно по подробнее? "эта дрянь" не только убирает encoding="WINDOWS-1251", но корежит русские буквы при сохранении

После того, как сделал загрузку из строки через loadXML, смотришь, есть ли processing instruction, если есть то заменяешь его своим, ну что-то типа:

      hr = doc->loadXML(bstrXML, &bSuccess);
      if (SUCCEEDED(hr)&&bSuccess) {
        CComPtr <IXMLDOMNode> instr;
        hr = doc->get_firstChild(&instr);
        if (SUCCEEDED(hr)) {
          DOMNodeType tp;
          instr->get_nodeType(&tp);
          if (tp==NODE_PROCESSING_INSTRUCTION) {
              CComPtr<IXMLDOMProcessingInstruction> pi = NULL;
              hr = instr->QueryInterface(__uuidof(IXMLDOMProcessingInstruction), (void**)&pi);
              if (SUCCEEDED(hr)) {
                CComBSTR instType(L"xml");
                CComBSTR instData(L"version=\"1.0\" encoding=\"WINDOWS-1251\"");
                CComPtr<IXMLDOMProcessingInstruction> ptrInstr;
                hr = doc->createProcessingInstruction(instType, instData,&ptrInstr);
                CComPtr<IXMLDOMNode> oldInstr;
                hr = doc->replaceChild(ptrInstr, instr, &oldInstr);

              }

          }
        }
Re[4]: Вопрос в эту тему
От: ain Россия  
Дата: 17.09.02 07:51
Оценка: 10 (1)
Здравствуйте Xenia, Вы писали:


X> wcstombs(sXML.GetBuffer(0),bstrXML,bstrXML.length());


X> mbstowcs(bstrXML,sXML,sXML.GetLength());


X>И этот код не работает в той части где должно происходить разбиение на строки описанным выше сособом. ПРичем не работает именно функция Replace, замены символов не происходит. В чем ошибка??


Попробуйте заменить:
wcstombs(sXML.GetBuffer(0),bstrXML,bstrXML.length());
на
sXML = (const char*)bstrXML;
и
mbstowcs(bstrXML,sXML,sXML.GetLength());
на
bstrXML = (LPCTSTR)sXML;
это работает, но то, что 100% правильно, не уверен.
... << J 1.0 alpha 4 >>
Re: MSXML
От: alsun  
Дата: 05.08.02 15:33
Оценка: 6 (1)
Здравствуйте Odi$$ey, Вы писали:

O$>Можно ли заставить MSXML парсер сохранять документы в структурированном виде? У меня шарошит весь файл в одну строку :(



<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
...



у меня работает... :)
MSXML
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 08.07.02 12:37
Оценка:
Можно ли заставить MSXML парсер сохранять документы в структурированном виде? У меня шарошит весь файл в одну строку
Re: MSXML
От: iLYA Канада http://www.bizon.org/ilya/
Дата: 08.07.02 18:00
Оценка:
Здравствуйте Odi$$ey, Вы писали:

O$>Можно ли заставить MSXML парсер сохранять документы в структурированном виде? У меня шарошит весь файл в одну строку :(

Прю...
Покопай в сторону
IXMLDOMDocument::preserveWhiteSpace — по моему, это то что доухтор прописал.

Удачи,
iLYA
Re[2]: MSXML
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 09.07.02 02:47
Оценка:
Здравствуйте iLYA , Вы писали:

O$>>Можно ли заставить MSXML парсер сохранять документы в структурированном виде? У меня шарошит весь файл в одну строку

I>Прю...

I>Покопай в сторону
I>IXMLDOMDocument::preserveWhiteSpace — по моему, это то что доухтор прописал.

дохтур, лекарство не действует как лепилось все в одну строку, так и лепится
Re: MSXML
От: Slayer Россия  
Дата: 09.07.02 02:52
Оценка:
Здравствуйте Odi$$ey, Вы писали:

O$>Можно ли заставить MSXML парсер сохранять документы в структурированном виде? У меня шарошит весь файл в одну строку

Не раз уже такой вопрос возникал — и ни разу я ответа не видел . Нельзя вроде бы это сделать с помощью парсера... Ручками надобно чего-нить дописывать...
Re[2]: MSXML
От: Slayer Россия  
Дата: 09.07.02 02:53
Оценка:
Здравствуйте Slayer, Вы писали:

S>Не раз уже такой вопрос возникал — и ни разу я ответа не видел . Нельзя вроде бы это сделать с помощью парсера... Ручками надобно чего-нить дописывать...


Либо можно еще в сторону XSLT посмотреть, но в XSLT я тебе к сожаленью не советчик
Re[3]: MSXML
От: ak_alex Россия  
Дата: 10.07.02 14:27
Оценка:
Круто. Правда эта дрянь, если в документе стояло:

<?xml version="1.0" encoding="WINDOWS-1251"?>


encoding="WINDOWS-1251" теряет навсегда, пришлось пересоздавать ProcessingInstruction.
Re[3]: MSXML
От: ak_alex Россия  
Дата: 30.07.02 11:28
Оценка:
Здравствуйте Odi$$ey, Вы писали:

Можно тоже самое но немного по другому:

Private Sub InsertNewlines(el_ As Object)
  Dim par_ As Object
  Set doc_=el_.OwnerDocument
  Set par_=el_.ParentNode
  
  ' Break after every opening tag
  If el_.HasChildNodes Then
    If el_.ChildNodes.Item(0).NodeType<>3 Then ' 3 - TEXT_NODE
      Set o=el_.InsertBefore(doc_.CreateTextNode(Chr$(13)+Chr$(10)),el_.ChildNodes.Item(0))
    End If
  End If
  ' Break after every closing tag
  If el_.NodeType<>3 And par_.NodeType<>9 Then ' 9 - DOCUMENT_NODE
    If el_.NextSibling Is Not Nothing Then
      Set o=par_.InsertBefore(doc_.CreateTextNode(Chr$(13)+Chr$(10)),el_.NextSibling)
    Else
      Set o=par_.AppendChild(doc_.CreateTextNode(Chr$(13)+Chr$(10)))
    End If
  End If

  ' Recursion
  For i=el_.ChildNodes.Length-1 To 0 Step -1
    Call InsertNewLines(el_.ChildNodes.item(i))
  Next i
End Sub

Public Sub SaveNiceXml(doc_ As Object,filename As String)
  Call InsertNewlines(doc_.DocumentElement)
  z%=doc_.save(filename)
  z%=doc_.load(filename)
  z%=doc_.save(filename)
End Sub

Sub Main
  Dim doc_ As Object
  Set doc_ = CreateObject("Microsoft.XMLDOM")
  z%=doc_.load("D:\Temp\xml\sm.xml")

  Call SaveNiceXml(doc_,"D:\Temp\xml\sm2.xml")
End Sub


Правда это на Rational Rose basic'е, но он почти VB
Re[4]: MSXML
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 22.08.02 09:15
Оценка:
Здравствуйте ak_alex, Вы писали:

AA>Круто. Правда эта дрянь, если в документе стояло:


AA>
AA><?xml version="1.0" encoding="WINDOWS-1251"?>
AA>


AA>encoding="WINDOWS-1251" теряет навсегда, пришлось пересоздавать ProcessingInstruction.


а можно по подробнее? "эта дрянь" не только убирает encoding="WINDOWS-1251", но корежит русские буквы при сохранении
Re[6]: MSXML
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 22.08.02 11:23
Оценка:
Здравствуйте ak_alex, Вы писали:

O$>>а можно по подробнее? "эта дрянь" не только убирает encoding="WINDOWS-1251", но корежит русские буквы при сохранении

AA>После того, как сделал загрузку из строки через loadXML, смотришь, есть ли processing instruction, если есть то заменяешь его своим, ну что-то типа:


OK, всё работает, после восстановления encoding="WINDOWS-1251", русские буквы при save() уже не корёжит.
Re[2]: MSXML
От: Андрей Россия  
Дата: 23.08.02 04:30
Оценка:
Здравствуйте alsun, Вы писали:

A><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

A> <xsl:output indent="yes"/>
A> ...

A>у меня работает...


А не мог бы ты поподробнее объяснить, куда эти stylesheets пихать, неужели прямо в xml-файл, который нужно структурировать? Я так понимаю, надо свой xml через трансформатор пропустить или я неправ?
Re[3]: Вопрос в эту тему
От: Xenia США  
Дата: 17.09.02 06:22
Оценка:
Ест такой XML файл

<?xml version="1.0"?>
<doc>
</doc>


И такой код на VC++ 6

CoInitialize(NULL);
    bool notEnd = TRUE;
    int i = 1;
    MSXML2::IXMLDOMDocumentPtr m_Output("MSXML2.DOMDocument.3.0");
    bool ret = m_Output->load("output1.xml");

    
    MSXML2::IXMLDOMNodePtr rootElement =  m_Output->selectSingleNode("doc");
    do
    {
        MSXML2::IXMLDOMNodePtr childNode =
            m_Output->createNode(CComVariant(NODE_ELEMENT),"Nom","");
        
                rootElement->appendChild(childNode);
        
                MSXML2::IXMLDOMElementPtr childElement = childNode;

        childElement->setAttribute("Mnemo",    CComVariant(m_Grid.GetItemText(i,1)));
        childElement->setAttribute("FullName", CComVariant(m_Grid.GetItemText(i,2)));
        childElement->setAttribute("Model",    CComVariant(m_Grid.GetItemText(i,3)));
        childElement->setAttribute("Price",    CComVariant(m_Grid.GetItemText(i,4)));
        childElement->setAttribute("SN",       CComVariant(m_Grid.GetItemText(i,8)));

        if ("" == m_Grid.GetItemText(++i,1)) notEnd = FALSE;

    }while(notEnd);


    _bstr_t bstrXML=L"";
    CString sXML="";


    bstrXML=m_Output->xml;
    wcstombs(sXML.GetBuffer(0),bstrXML,bstrXML.length());
    
    
    int b= sXML.Replace("><",">\n<");
    mbstowcs(bstrXML,sXML,sXML.GetLength());
    
    
    m_Output->loadXML(bstrXML);
    m_Output->save("res.xml");

CoUninitialize();


И этот код не работает в той части где должно происходить разбиение на строки описанным выше сособом. ПРичем не работает именно функция Replace, замены символов не происходит. В чем ошибка??
Re[4]: Вопрос в эту тему
От: Lloyd Россия  
Дата: 17.09.02 08:00
Оценка:
Здравствуйте Xenia, Вы писали:

X>И этот код не работает в той части где должно происходить разбиение на строки описанным выше сособом. ПРичем не работает именно функция Replace, замены символов не происходит. В чем ошибка??


А по какому признаку Вы определили, что не происходит замены символов?

Если потому что их нет в "res.xml", то их там и не должно быть. Попробуйте саму строку bstrXML записать в файл и посмотрите, что получится. Может будет то, что Вам надо.
Re[5]: Вопрос в эту тему
От: ain Россия  
Дата: 17.09.02 08:08
Оценка:
Здравствуйте Lloyd, Вы писали:

L>Здравствуйте Xenia, Вы писали:


X>>И этот код не работает в той части где должно происходить разбиение на строки описанным выше сособом. ПРичем не работает именно функция Replace, замены символов не происходит. В чем ошибка??


L>А по какому признаку Вы определили, что не происходит замены символов?


L>Если потому что их нет в "res.xml", то их там и не должно быть. Попробуйте саму строку bstrXML записать в файл и посмотрите, что получится. Может будет то, что Вам надо.


int b= sXML.Replace("><",">\n<");
b == 0
... << J 1.0 alpha 4 >>
Re[5]: Вопрос в эту тему
От: Xenia США  
Дата: 17.09.02 11:00
Оценка:
Спасибо, заработало!!!
Re[5]: Вопрос в эту тему
От: Xenia США  
Дата: 17.09.02 11:04
Оценка:
Здравствуйте Lloyd, Вы писали:

L>Здравствуйте Xenia, Вы писали:


X>>И этот код не работает в той части где должно происходить разбиение на строки описанным выше сособом. ПРичем не работает именно функция Replace, замены символов не происходит. В чем ошибка??


L>А по какому признаку Вы определили, что не происходит замены символов?


1. По возвращаемому функцией Replace значению
2. Файл как был в одну сроку так и остается
Re: MSXML - сохранение с отступами - 1
От: Аноним  
Дата: 22.09.05 14:00
Оценка:
OE>
OE>        CComBSTR bstrXML( L"" );
OE>        hr = spDomDocument->get_xml( &bstrXML ); // CComPtr<IXMLDOMDocument> spDomDocument;

OE>        // вставляем переводы строки
OE>        CString sXml = W2A( bstrXML );
OE>        sXml.Replace( "><", ">\n<" );OE>        bstrXML = sXml.GetBuffer( 0 );

OE>        // загружаем взад
OE>        hr = spDomDocument->loadXML( bstrXML, &bSuccess );

OE>        // сохраняем файлы
OE>        hr = spDomDocument->save( CComVariant( L"file.xml") );
OE>


OE>получается чудненько структурированный документ со всеми отступами.


Откуда берутся отступы, если вставляются только переводы строк?
Re[4]: Вопрос в эту тему
От: Maslex  
Дата: 26.09.05 08:09
Оценка:
Ну вставлю и свои пять копеек.
Вот смотрю и диву даюсь, сколько народу мучается с тем чтобы нормально XML-ку сохранить.
Когда-то и я мучался.
Вот мой вариант, с использованием IMXWriter, который кстати позволяет сохранять данные в любой кодировке.
В примере ниже: сохраняется в строку в UTF-8 кодировке.

HRESULT XML2UTF8Encoding(const CString& szBody, std::string& szRequest)
{
   IXMLDOMDocument2Ptr pIXMLDOMDocument;
   HRESULT hr = pIXMLDOMDocument.CreateInstance(__uuidof(DOMDocument40));
   if(FAILED(hr))
      return hr;

   pIXMLDOMDocument->resolveExternals = VARIANT_FALSE;
   pIXMLDOMDocument->async = VARIANT_FALSE;
   pIXMLDOMDocument->validateOnParse = VARIANT_FALSE;

   if(::loadXML(pIXMLDOMDocument, _bstr_t(szBody)) != VARIANT_TRUE)
   {
      return E_FAIL;
   }

   ISAXXMLReaderPtr pReader;
   hr = pReader.CreateInstance(__uuidof(SAXXMLReader40));

   IMXWriterPtr pWriter;
   hr = pWriter.CreateInstance(__uuidof(MXXMLWriter40));
   if(FAILED(hr))
      return hr;

   //Set properties on the XML writer.
   pWriter->byteOrderMark = VARIANT_FALSE;
   pWriter->omitXMLDeclaration = VARIANT_FALSE;
   pWriter->indent = VARIANT_TRUE;
   pWriter->encoding = "UTF-8";
   
   //Set the XML writer to the SAX content handler.
   pReader->putContentHandler((ISAXContentHandlerPtr)pWriter);
   pReader->putDTDHandler((ISAXDTDHandlerPtr)pWriter);
   pReader->putErrorHandler((ISAXErrorHandlerPtr)pWriter);

   CComPtr<IStream> m_spIStream;
   hr = CreateStreamOnHGlobal(NULL, TRUE, &m_spIStream);
   if(FAILED(hr))
      return hr;

   pWriter->output = _variant_t(m_spIStream);
   hr = pReader->parse((_variant_t)pIXMLDOMDocument.GetInterfacePtr());
   if(FAILED(hr))
      return hr;
   
   LARGE_INTEGER iLNull = {0, 0};
   ULARGE_INTEGER uLLen = {0, 0};
   //Take data size...
   hr = m_spIStream->Seek(iLNull, STREAM_SEEK_CUR, &uLLen);
   if(FAILED(hr))
      return hr;
   //IStream -> to begin...
   hr = m_spIStream->Seek(iLNull, STREAM_SEEK_SET, NULL);
   if(FAILED(hr))
      return hr;
   //Size of buffer...
   DWORD Size = (DWORD)uLLen.QuadPart;
   
   char * szBuf = new char[Size+1];
   m_spIStream->Read(szBuf, Size, NULL);
   szBuf[Size] = 0;
   szRequest = szBuf;
   delete []szBuf;
   return NOERROR;
}
... << RSDN@Home 1.2.0 alpha rev. 605>>
WBR,
Maslex
Re[2]: MSXML - сохранение с отступами - 1
От: Аноним  
Дата: 28.09.05 07:32
Оценка:
Здравствуйте, Аноним, Вы писали:

OE>>
OE>>        CComBSTR bstrXML( L"" );
OE>>        hr = spDomDocument->get_xml( &bstrXML ); // CComPtr<IXMLDOMDocument> spDomDocument;

OE>>        // вставляем переводы строки
OE>>        CString sXml = W2A( bstrXML );
OE>>        sXml.Replace( "><", ">\n<" );OE>        bstrXML = sXml.GetBuffer( 0 );

OE>>        // загружаем взад
OE>>        hr = spDomDocument->loadXML( bstrXML, &bSuccess );

OE>>        // сохраняем файлы
OE>>        hr = spDomDocument->save( CComVariant( L"file.xml") );
OE>>


OE>>получается чудненько структурированный документ со всеми отступами.


А>Откуда берутся отступы, если вставляются только переводы строк?


Эээээй!!? Никто не знает или все проморозились?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.