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

Если название форума вам о чём-то говорит, то значит, внутри вы найдете что-то для себя полезное.
jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

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

Сообщение jangle » 31.07.2007 (Вт) 11:57

Пытаюсь влезть в новую для себя тему - работу с 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

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 31.07.2007 (Вт) 12:17

Потому что в этой ноде нет текста.
Изображение

RayShade
Scarmarked
Scarmarked
Аватара пользователя
 
Сообщения: 5511
Зарегистрирован: 02.12.2002 (Пн) 17:11
Откуда: Russia, Saint-Petersburg

Сообщение RayShade » 13.08.2007 (Пн) 8:20

Очень странный запрос для 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 не знаю, будет работать или нет, но логика надеюсь понятна.
I don't understand. Sorry.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 20.08.2007 (Пн) 10:40

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

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

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



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

Thomas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 246
Зарегистрирован: 12.11.2005 (Сб) 0:17
Откуда: "Сказочное королевство"

Сообщение Thomas » 20.08.2007 (Пн) 23:24

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()
Met vriendelijke groetjes
VS2008 Pro FW3.5 SP1

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 21.08.2007 (Вт) 8:31

Thomas писал(а):jangle
Приветствую.
Попробуй использовать XmlTextReader.


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

Thomas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 246
Зарегистрирован: 12.11.2005 (Сб) 0:17
Откуда: "Сказочное королевство"

Сообщение Thomas » 21.08.2007 (Вт) 19:09

jangle
Oops. :oops:
Я учусь писать на .NET. 8)
Если честно, то не знаю. :roll:
Met vriendelijke groetjes
VS2008 Pro FW3.5 SP1

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 22.08.2007 (Ср) 11:01

Вобщем с 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)

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 22.08.2007 (Ср) 11:36

Регулярные выражения?
Я бы лучше автомат сделал, на InStr. У XML структура строгая, проблем быть не должно.
В кирпичах лежит самодельный парсер HTML, его можно значительно упростить и прикрутить к XML.
Lasciate ogni speranza, voi ch'entrate.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.08.2007 (Ср) 12:05

Ну раз уже всё равно написал свой код, то не жалко правильный показать :-)

Код: Выделить всё
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
Изображение

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 22.08.2007 (Ср) 14:08

Ну раз уже всё равно написал свой код, то не жалко правильный показать


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

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.08.2007 (Ср) 14:11

Твой XML-то у тебя у самого грузится? ;-)
(Например, в IE открывается?)
Изображение

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 22.08.2007 (Ср) 14:20

В IE он не откроется, т.к. это "XML based Configuration file", проще говоря аналог древнего INI файла. В нем XML .Net приложения сериализуют свои настройки.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.08.2007 (Ср) 14:27

В IE открывается любой синтаксически корректный XML-файл.
Значит, твой некорректный, раз не открывается.
Вместо разводить демагогию, дописал бы лучше в свой код: MsgBox xmlDoc.parseError.reason
Изображение

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 22.08.2007 (Ср) 14:39

В IE открывается любой синтаксически корректный XML-файл.
Значит, твой некорректный, раз не открывается


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

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 22.08.2007 (Ср) 14:45

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


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

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

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

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 22.08.2007 (Ср) 14:53

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


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

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 07.11.2007 (Ср) 18:14

возможно его не на MSXML парсят.


Вернуться в XML/XSL/XHTML

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5

    TopList  
cron