Страница 1 из 1

Парсинг XML конфигов

СообщениеДобавлено: 31.07.2007 (Вт) 11:57
jangle
Пытаюсь влезть в новую для себя тему - работу с XML. Задача такая, имеется конфиг в формате XML, и в нем надо заменит строку <add key="SqlType" value="MSSQL" /> на <add key="SqlType" value="ORA" />.

Можно конечно сделать это и обычным парсингом строк, но хочется сделать через XML


Код: Выделить всё
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="AKDWinApp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <appSettings>
     <add key="PortalSettingCaching" value="1000" />
     <!--
          SqlType - возможны 2 варианта :
              <add key="SqlType"            value="ORA" />
              <add key="SqlType"            value="MSSQL" />
    -->
     <add key="SqlType" value="MSSQL" />
     <add key="ActiveXSqlType" value="MSSQL" />
     <add key="OracleConnectionString" value="Data Source=hp;Pooling=true;User ID=aserg2;Password=222222" />
     <add key="MSSQLConnectionString" value="Data Source=hpia64;Initial Catalog=ZUBR030707;Persist Security Info=False;User ID=aserg;Password=111111" />
    <!--<add key="MSSQLConnectionString" value="Data Source=BGSK-IT044\SQLEXPRESS;Initial Catalog=Zubr;Persist Security Info=False;User ID=sa;Password=qazwsx" />-->
     <add key="WebServiceConnectionString" value="http://10.10.40.9/AKDWS/" />

     <add key="CatalogLogs" value="log" />
     <add key="CatalogIcons" value="icons" />
     <!-- Расстояние от обьекта до границы области видимости в метрах -->
     <add key="Boundary" value="200" />
     <add key="MBRInflate" value="0.1" />
     <!-- базовый каталог вордовых документов -->
     <add key="CatalogWord" value="http://10.10.40.9/AKDData/" />
     <!-- Настройки GPS -->
     <add key="gpsPort" value="COM3" /> 
    <add key="gpsDelay" value="5" />
    <add key="synchPackageSize" value="300" />
    <!-- settings for UnhandledExceptionManager class -->
    <add key="UnhandledExceptionManager/LogToEventLog" value="true" />
  </appSettings>
  <!--<system.windows.forms jitDebugging="true" />-->
  <applicationSettings>
    <AKDWinApp.Properties.Settings>
      <setting name="AKDWinApp_SynchronizationService_Synchronization"
        serializeAs="String">
        <value>http://localhost/AKDWS/Synchronization.asmx</value>
      </setting>
    </AKDWinApp.Properties.Settings>
  </applicationSettings>
</configuration>



Для начала, хочу получить содержимое <appSettings>, но почему возвращается пустая строка?

Код: Выделить всё
Private Sub Command1_Click()
    Dim xmlDoc As MSXML2.DOMDocument30
    Dim objNode As IXMLDOMNode
    Set xmlDoc = New DOMDocument30
    xmlDoc.async = False
    xmlDoc.validateOnParse = False
    xmlDoc.Load ("C:\App.exe.config.xml")
    xmlDoc.setProperty "SelectionLanguage", "XPath"
    Set objNode = xmlDoc.selectSingleNode("//configuration/appSettings/*")
   
    MsgBox objNode.Text

End Sub

СообщениеДобавлено: 31.07.2007 (Вт) 12:17
tyomitch
Потому что в этой ноде нет текста.

СообщениеДобавлено: 13.08.2007 (Пн) 8:20
RayShade
Очень странный запрос для selectSingleNode. * обычно используется в selectNodes - для коллекции.



А еще и в самом деле у выбираемых нодов нет текста.



Я бы писал так:



Код: Выделить всё
Private Sub Command1_Click()
    Dim xmlDoc As MSXML2.DOMDocument30
    Dim objNode As IXMLDOMNode
    Set xmlDoc = New DOMDocument30
    xmlDoc.async = False
    xmlDoc.validateOnParse = False
    xmlDoc.Load ("C:\App.exe.config.xml")
    xmlDoc.setProperty "SelectionLanguage", "XPath"
    Set objNodes = xmlDoc.selectNodes("//configuration/appSettings/*")

For Each objNode in objNodes

MsgBox objNode.attributes.getNamedItem("value").nodeTypedValue

Next objNode
   
End Sub




For Each не знаю, будет работать или нет, но логика надеюсь понятна.

СообщениеДобавлено: 20.08.2007 (Пн) 10:40
jangle
RayShade писал(а):Очень странный запрос для selectSingleNode. * обычно используется в selectNodes - для коллекции.

А еще и в самом деле у выбираемых нодов нет текста.

Я бы писал так:



Код не работает, по прежнему выводятся пустые мессанджбоксы

СообщениеДобавлено: 20.08.2007 (Пн) 23:24
Thomas
jangle
Приветствую.
Попробуй использовать XmlTextReader.
Код: Выделить всё

Dim rd As XmlTextReader = New XmlTextReader(fileName)
Dim text As String = ""
Do While rd.Read()
            Select Case rd.NodeType
                Case XmlNodeType.Element
                    Select Case rd.Name
                        Case "configSections"
                            rd.Skip() ' проскакиваем элемент
                        Case "add" ' читаем элемент с именем add
                            rd.MoveToFirstAttribute()
                            text &= rd.Value & vbTab
                            rd.MoveToAttribute("value")
                            text &= rd.Value & vbCrLf
                    End Select
                Case XmlNodeType.Text
                    'делай что-то
            End Select
        Loop
TextBox2.Text = text


Я так у себя входящие xml разбираю. Когда знаешь какие там элементы, то довольно удобно. Чтобы пропускать не нужные элементы и все что в них используй
Код: Выделить всё

Case "MailingCreate"
                            rd.Skip()

СообщениеДобавлено: 21.08.2007 (Вт) 8:31
jangle
Thomas писал(а):jangle
Приветствую.
Попробуй использовать XmlTextReader.


Thomas - дело в том, что я пишу на VB6. В нем можно использовать этот класс?

СообщениеДобавлено: 21.08.2007 (Вт) 19:09
Thomas
jangle
Oops. :oops:
Я учусь писать на .NET. 8)
Если честно, то не знаю. :roll:

СообщениеДобавлено: 22.08.2007 (Ср) 11:01
jangle
Вобщем с XML пока не разобрался, сделал парсер на регулярных выражениях. Работает стабильно

Код: Выделить всё
    Dim myRegExp As New RegExp
    myRegExp.IgnoreCase = True
    myRegExp.Global = True
    myRegExp.Pattern = "<\s*add\s* key\s*=\s*""ActiveXSqlType""\s* value\s*=\s*" & Chr$(34)
    temp = myRegExp.Replace(temp, "<add key=""ActiveXSqlType"" value=" & Chr$(34) & DB)
    myRegExp.Pattern = "<\s*add\s* key\s*=\s*""SqlType""\s* value\s*=\s*" & Chr$(34)
    temp = myRegExp.Replace(temp, "<add key=""SqlType"" value=" & Chr$(34) & DB)

СообщениеДобавлено: 22.08.2007 (Ср) 11:36
alibek
Регулярные выражения?
Я бы лучше автомат сделал, на InStr. У XML структура строгая, проблем быть не должно.
В кирпичах лежит самодельный парсер HTML, его можно значительно упростить и прикрутить к XML.

СообщениеДобавлено: 22.08.2007 (Ср) 12:05
tyomitch
Ну раз уже всё равно написал свой код, то не жалко правильный показать :-)

Код: Выделить всё
Option Explicit

Sub Main()
    Dim xmlDoc As MSXML2.DOMDocument
    Set xmlDoc = New DOMDocument
    xmlDoc.async = False
    xmlDoc.validateOnParse = False
    xmlDoc.Load ("C:\App.exe.config.xml")
    xmlDoc.setProperty "SelectionLanguage", "XPath"
    Dim objNode As IXMLDOMNode, objAttr As IXMLDOMAttribute
    For Each objNode In xmlDoc.selectNodes("//add[@key='SqlType' and @value='MSSQL']")
        Set objAttr = objNode.Attributes.getNamedItem("value")
        objAttr.Value = "ORA"
    Next
    MsgBox xmlDoc.xml
End Sub

СообщениеДобавлено: 22.08.2007 (Ср) 14:08
jangle
Ну раз уже всё равно написал свой код, то не жалко правильный показать


Что-то у меня твой код не работает, цикл For Each вообще ни разу не срабатывает, мессанджбокс выводится пустым.

СообщениеДобавлено: 22.08.2007 (Ср) 14:11
tyomitch
Твой XML-то у тебя у самого грузится? ;-)
(Например, в IE открывается?)

СообщениеДобавлено: 22.08.2007 (Ср) 14:20
jangle
В IE он не откроется, т.к. это "XML based Configuration file", проще говоря аналог древнего INI файла. В нем XML .Net приложения сериализуют свои настройки.

СообщениеДобавлено: 22.08.2007 (Ср) 14:27
tyomitch
В IE открывается любой синтаксически корректный XML-файл.
Значит, твой некорректный, раз не открывается.
Вместо разводить демагогию, дописал бы лучше в свой код: MsgBox xmlDoc.parseError.reason

СообщениеДобавлено: 22.08.2007 (Ср) 14:39
jangle
В IE открывается любой синтаксически корректный XML-файл.
Значит, твой некорректный, раз не открывается


Файл корректный, его использует довольно сложная клиент-серверная система для хранения своих настроек. Написана она на Visual Studio 2005 под .Net Framework 2.0 Там таких XML конфигов несколько десятков, изменяя их можно выполнять точную юстировку системы.

СообщениеДобавлено: 22.08.2007 (Ср) 14:45
tyomitch
jangle писал(а):
В IE открывается любой синтаксически корректный XML-файл.
Значит, твой некорректный, раз не открывается


Файл корректный

"Какие ваши доказателства?" (c)

Если бы он был корректный, IE бы его открывал.
Если он корректный, тогда почему IE его не открывает?

СообщениеДобавлено: 22.08.2007 (Ср) 14:53
jangle
Если бы он был корректный, IE бы его открывал.
Если он корректный, тогда почему IE его не открывает?


Ну тогда не знаю, может программу изначально научили работать с некоректным XML? Может это ошибка людей писавших эту систему?
Или они специально сделали его неправильным?
Вобщем проблему удалось решить регулярными выражениями.

СообщениеДобавлено: 07.11.2007 (Ср) 18:14
Konst_One
возможно его не на MSXML парсят.