Reputation: 790
I'm updating a small xml file. The input has line breaks within an attribute, as shown here:
<foo>
<add name="bar"
attr1="aaaa;
bbbbb;
cccc"/>
</foo>
The output; however, looks like this (with line feeds)
<foo>
<add name="bar" attr1="aaaa;
 bbbbb;
 cccc"/>
</foo>
I've tried several ways to locate and remove the line feeds.
A workaround is to not have the line feeds in the input. However, I'd like to leave the line feeds in the input, for readability. I'd prefer to leave them in the output also, however, that's not necessary.
How might I control the line feeds in the output, either by having them be "real" line feeds, or deleting them?
Below is the test routine which replicates the problem; it does no data update, like the real routine does. The real routine works fine except for the line feeds.
Sub Test()
On Error GoTo ErrTrap:
Dim XMLDoc As New MSXML2.DOMDocument60
Dim wrkInFolder As String
Dim wrkInFullPath As String
Dim wrkOutFolder As String
Dim wrkOutFullPath As String
Dim wrkCSNode As IXMLDOMNode
Dim wrkDataCS As IXMLDOMNode
Dim wrkAttr As IXMLDOMAttribute
Dim wrkInVal As String
Dim wrkOutVal As String
'---- set up the I/O Paths
wrkInFolder = "D:\mypath\"
wrkInFullPath = wrkInFolder & "xmltest.config"
wrkOutFolder = wrkInFolder
wrkOutFullPath = wrkOutFolder & "xmltest-out.config"
'---- get the doc
XMLDoc.Load (wrkInFullPath)
'--- get conn str node
Set wrkCSNode = XMLDoc.SelectSingleNode("foo")
'--- first child node (base 0)
Set wrkDataCS = wrkCSNode.ChildNodes(0)
'--- first attribute (base 0)
Set wrkAttr = wrkDataCS.Attributes(0)
'---- get the value of the attribute
wrkInVal = wrkAttr.NodeValue
wrkOutVal = Replace(wrkInVal, "
", "")
p1 = InStr(wrkOutVal, "
")
If p1 <> 0 Then
MsgBox ("Found line feed")
End If
wrkAttr.NodeValue = wrkOutVal
XMLDoc.Save (wrkOutFullPath)
On Error GoTo 0
Exit Sub
ErrTrap:
Dim exmsg As String
exmsg = Err.Description
Dim wrkStop As String
wrkStop = ""
On Error GoTo 0
End Sub
Upvotes: 0
Views: 203
Reputation: 107687
What you are referring to is actually whitespace, not linefeeds. You can restyle the XML using XSLT. Then, the whitespace within an attribute value an be handled with XSLT's normalize-space()
function.
As background, XSLT is a special-purpose declarative language to transform/style XML to any restructured format. In VBA (like many other programming languages), you can load XSLT externally (just like your XML file) or as an inline string. Below is the external file route:
XSLT (almost an identity transform to clone structure but removing white space in attribute value)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="normalize-space()"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
VBA (loads both .config xml and .xsl file in wrkInFolder and transforms into outputted .config file)
Dim XMLDoc As New MSXML2.DOMDocument60
Dim XSLDoc As New MSXML2.DOMDocument60
Dim OutputXML As New MSXML2.DOMDocument60
Dim wrkInFolder As String, wrkInFullPath As String
Dim wrkOutFolder As String, wrkOutFullPath As String
'---- Set up the I/O Paths
wrkInFolder = "D:\mypath\"
wrkInFullPath = wrkInFolder & "xmltest.config"
wrkOutFolder = wrkInFolder
wrkOutFullPath = wrkOutFolder & "xmltest-out.config"
'---- Load xml data
XMLDoc.async = False
XMLDoc.Load wrkInFullPath
'---- Load xslt stylesheet
XSLDoc.async = False
XSLDoc.Load wrkInFolder & "xslfile.xsl" ' SAVE ABOVE EXTERNALLY IN .xsl FORMAT
'---- Do the transform
XMLDoc.transformNodeToObject XSLDoc, OutputXML
OutputXML.Save wrkOutFullPath
Upvotes: 1