>Hi Carlos,
>
>Try
>
>loXML = CREATEOBJECT( "MSXML2.DOMDocument" )
>...
>loParentNode = loXML.selectSingleNode("settings/node2/subnode2")
>loElement = loParentNode.appendChild(loXMl.createElement("field4"))
>loElement.nodeTypedValue = "Data224"
>
>
Hi Sergey, thank you for your response. I think I was not clear, but I managed to code a solution. The problem was setting an element value in cases when the node does not exist.
For example, lets say we have an empty XML file like this one:
<?xml version="1.0" encoding="UTF-8"?>
<settings>
</settings>
And I want to save a setting like for example : m.tcSettingName = "settings/node/subnode/element", m.tcSettingValue = "elementvalue"
This is the code I came up with:
Lparameter tcSettingName, tcSettingValue
m.loXml = Createobject("MsXml2.DomDocument")
m.loXml.Async = .F.
m.loXml.Load(This._FileName)
m.lcSettingName = Lower(Chrtran(m.tcSettingName, "\", "/"))
m.loElement = m.loXml.DocumentElement.SelectSingleNode(m.lcSettingName)
If Vartype(m.loElement) = T_OBJECT Then
m.loElement.Text = m.tcSettingValue
Else
If "/" $ m.lcSettingName Then
m.lcPath = "/"
For m.lnx = 1 To Getwordcount(m.lcSettingName, "/")
m.loNode = m.loXml.DocumentElement.SelectSingleNode(m.lcPath + "/" + Getwordnum(m.lcSettingName, m.lnx, "/"))
If Vartype(m.loNode) # T_OBJECT Then
If m.lcPath == "/" Then
m.loNode = m.loXml.DocumentElement
Else
m.loNode = m.loXml.DocumentElement.SelectSingleNode(m.lcPath)
Endif
m.loNode.appendChild(m.loXml.createNode(NODE_ELEMENT, Getwordnum(m.lcSettingName, m.lnx, "/"),""))
Endif
m.lcPath = m.lcPath + "/" + Getwordnum(m.lcSettingName, m.lnx, "/")
Endfor
m.loElement = m.loXml.DocumentElement.SelectSingleNode(m.lcSettingName)
m.loElement.Text = m.tcSettingValue
Else
m.loRoot = m.loXml.DocumentElement
m.loRoot.appendChild(m.loXml.CreateElement(m.lcSettingName))
m.loRoot.LastChild.Text = m.tcSettingValue
Endif
Endif
m.loXml.LoadXML(This._FormatXml(m.loXml.XML))
m.loXml.Save(This._FileName)
This seems to work OK, but since this is the first time I have to work with XML, I don´t really know if this is best way/correct way.
By the way, I discovered that the saved XML had no linefeeds! And since the whole idea is to have a settings file that can be easily edited by hand, I had to add
the _FormatXml method:
Lparameters tcXml As String
Local ;
lcXsl As String, ;
loXml As MsXml2.DomDocument, ;
loXsl As MsXml2.DomDocument
TEXT To m.lcXsl NoShow
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
ENDTEXT
m.loXml = Createobject("MsXml2.DomDocument")
m.loXml.LoadXML(m.tcXml)
m.loXsl = Createobject("MsXml2.DomDocument")
m.loXsl.LoadXML(m.lcXsl)
m.lcXml = m.loXml.TransformNode(m.loXsl)
m.loXml = .Null.
m.loXsl = .Null.
m.lcXml = Strtran(m.lcXml, 'UTF-16', 'UTF-8')
Return m.lcXml
Again, I don´t know if this is "correct", but it works.
Carlos Alloatti