2016-06-17 2 views
0

私がここで使っているスクリプトは、XMLファイルを使って再帰を試み、各RegExの一致(検索配列に格納されている)を2つの結果配列に格納することです。開始日は1、終了日は1です。 両方の配列のUboundが等しいかどうかがチェックされた後、XMLDOMを使用して各親ノードのEnd_Dateノードを検索し、そのテキストを別の関数に渡して30日を追加した後、値。次に、内容をファイルに書き戻して保存することになっています。For-EachのXML値を置き換えて関数内に戻す

ここにいくつかの問題があります。 1.最初の親ノードを通過したものに+30日の値を戻すことはできません。メモリ空間は、以前のFor-Each反復の+ 30日の値を保持しているようです。 2.ファイルに何も書き込むことはできません。

私は当初、テキストファイル用に書いていましたが、私たちのプロジェクトで変更された要件としてXML形式に変更されました。

私はこれをすべてvbscriptのXMLDOMで行い、関数を使用して特定のデータ変更を行うことができればと思っています。しかし、私の主な懸念は、私のちょっとしたスクリプトが基本的なことをしていないことです。

実行中のループの脆弱性を指摘してもらえますか?私は壁にぶつかり、それ以上の進歩を遂げることはできません!

ここで私は(削除された子ノードのトン/ wの2つの広告ノードに短縮)読んでいるXMLファイルです:

<?xml version="1.0" encoding="utf-8"?> 
<XMLFeederRoot> 
<ADS_CREATE_TIME>2016-06-07T01:35:39</ADS_CREATE_TIME> 
<Ad> 
    <Ad_Number>d00524224</Ad_Number> 
    <Start_Date>2016-08-20T00:00:00</Start_Date> 
    <End_Date>2016-08-20T00:00:00</End_Date> 
    <Status>Run</Status> 
</Ad><Ad> 
    <Ad_Number>d00524225</Ad_Number> 
    <Start_Date>2016-08-20T00:00:00</Start_Date> 
    <End_Date>2016-08-20T00:00:00</End_Date> 
    <Status>Run</Status> 
</Ad> 
</XMLFeederRoot> 

はここにスクリプトです:

'Setting the Regular Expression object and setting occurrences to all in strings searched. 
Set objRegEx= CreateObject("VBScript.RegExp") 
objRegEx.Global= True 

set Shell= createobject("wscript.shell") 
Dim FSO, FLD, FIL, TS, strDate, strEDat, i, d, c 
Dim strFolder, strContent, strPath 
Const ForReading= 1, ForWriting= 2 

strFolder= "C:\Scripts\Run" 

Set FSO= CreateObject("Scripting.FileSystemObject") 

'Get a reference to the folder you want to search 
set FLD= FSO.GetFolder(strFolder) 

'loop through the folder and get the files 
For Each Fil In FLD.Files 

'Open the file to read 
Set TS= FSO.OpenTextFile(fil.Path, ForReading) 

'Read the contents into a variable 
strContent= TS.ReadAll 

'Close the file 
TS.Close 


reDim arrMR(1,1) 
    arrMR(0,0)= "(\s+)(<Start_Date>(.*?)<\/Start_Date>)" 
    arrMR(1,0)= "(\s+)(<End_Date>(.*?)<\/End_Date>)" 


For i= 0 to Ubound(arrMR) 
    objRegEx.Pattern= arrMR(i,0) 
    Set objMatches= objRegEx.Execute(strContent) 


d=0 

    For Each objMatch in objMatches 
     If i= 0 Then 
      If d>0 Then 
       reDim Preserve arrStart(d) 
      Else 
       reDim arrStart(d) 
      End If 
       arrStart(d)= objMatches.Item(d).SubMatches(2) 

       'Wscript.Echo arrStart(d) 
     ElseIf i<> 0 Then 
      If d>0 Then 
       reDim Preserve arrEnd(d) 
       ReDim Preserve arrMatch1(d) 
      Else 
       reDim arrEnd(d) 
       ReDim arrMatch1(d) 
      End If 
       arrEnd(d)= objMatches.Item(d).SubMatches(2)   
       arrMatch1(d)= objMatches.Item(d).SubMatches(1) 

     End If 



     If objRegEx.Pattern<> arrMR(0,0) Then 
      If (ubound(arrStart)= ubound(arrEnd)) Then 
       'Wscript.Echo "Ubounds Match" 
          Parse strContent 
          strContent= Parse(strContent) 
      Else 
       'Wscript.Echo "Start & End Dates do not match" 
      End If 
     End If   
      d= d+ 1 'increment to next match 

    Next 

Next  

'Close the file 
TS.Close 

'Open the file to overwrite the contents 
Set TS= FSO.OpenTextFile(fil.Path, ForWriting) 

'Write the contents back 
TS.Write strContent 

'Close the current file 
TS.Close 

Next 

'Clean up 
Set TS= Nothing 
Set FLD= Nothing 
Set FSO= Nothing 


Function Parse(ParseContent) 

    'Dim sFSpec : sFSpec = FSO.GetAbsolutePathName("C:\Users\j.levine\Desktop\XML Feeder     Scripts\Test_Files\monvid.txt") 
    Dim oXML : Set oXML = CreateObject("Msxml2.DOMDocument.6.0") 
    Dim strXMLSDat, strXMLarrStartD, XMLEDat 
    oXML.setProperty "SelectionLanguage", "XPath" 
    oXML.async = False 
    oXML.loadXML(ParseContent) 

    If 0 = oXML.parseError Then 
    Dim sXPath3 : sXPath3 = "//XMLFeederRoot/Ad[End_Date=Start_Date]" 
    Dim ndlFnd : Set ndlFnd = oXML.selectNodes(sXPath3) 
    If 0 = ndlFnd.length Then 
     WScript.Echo sXPath, "not found" 
    ElseIf 0<> ndlFnd.length Then  
     'WScript.Echo "found", ndlFnd.length, "nodes for", sXPath 
     Dim ndCur, oldNode 
     For Each ndCur In ndlFnd  
      oldNode = oXML.selectsinglenode("//End_Date").text 
      oldNode= XMLSplitArray(oldNode) 'Pass current Date into Array and add 30 days & return as node text 
      Set newNode= oXML.selectSingleNode("//End_Date") 
      newNode.text= oldNode 
      WScript.Echo ndCur.xml 

     Next 
     'WScript.Echo "We have nothing to replace" 
    End If 
    Else 
    WScript.Echo oXML.parseError.reason 
    End If 

    Parse= ParseContent 
End Function 


Function XMLSplitArray(strval1) 

dim XmlSA, XmlSA2, XMLEDat 

XmlSA = split(strval1, "-") 
XmlSA(2) = Left(XmlSA(2), 2) 
strXMLDate = XmlSA(1) & "/" & XmlSA(2) & "/" & XmlSA(0) 
strXMLDate30 = DateAdd("d", 30, strXMLDate) 

XmlSA2 = split(strXMLDate30, "/") 

'Add zero to the left 
XmlSA2(0)= Right("0" & XmlSA2(0), 2) 
XmlSA2(1)= Right("0" & XmlSA2(1), 2) 

XmlSA2(1) = XmlSA2(1) & "T00:00:00" 
XMLEDat = XmlSA2(2) & "-" & XmlSA2(0) & "-" & XmlSA2(1) 
XMLSplitArray= XMLEDat 

End Function 

答えて

0

テキストおよびXMLので、ファイルはデフォルトでファイルロックを使用せず、xmlDoc.Save monvidPathを使用して元のファイルを上書きします。

Sub setAdEndDate(monvidPath) 
    Const sXPath = "/XMLFeederRoot/Ad/End_Date" 

    Set xmlDoc = CreateObject("Microsoft.XMLDOM") 

    xmlDoc.Async = "False" 
    xmlDoc.Load(monvidPath) 

    Set colNodes=xmlDoc.selectNodes(sXPath) 

    For Each n In colNodes 

     n.Text = SplitArray(n.Text) 

    Next 

    xmlDoc.Save monvidPath 

End Sub 

Function SplitArray(strval1) 
    Dim SplitArray1, SplitArray2, strSDat 

    splitArray1 = Split(strval1, "-") 
    splitArray1(2) = Left(splitArray1(2), 2) 
    strDate1 = SplitArray1(1) & "/" & SplitArray1(2) & "/" & SplitArray1(0) 
    strDate30 = DateAdd("d", 30, strDate1) 

    SplitArray2 = Split(strDate30, "/") 

    'Add zero to the left 
    If Len(SplitArray2(0))<2 Then 
     SplitArray2(0)= Right("0" & SplitArray2(0), 2) 
    End If 
    If Len(SplitArray2(1))<2 Then 
     SplitArray2(1)= Right("0" & SplitArray2(1), 2) 
    End If 

    SplitArray2(1) = splitArray2(1) & "T00:00:00" 
    strSDat = SplitArray2(2) & "-" & SplitArray2(0) & "-" & SplitArray2(1) 
    SplitArray= strSDat 

End Function 
+0

、はい、これは容易になるだろうと私は彼らのように除去このスクリプトの他の部分でそれをやりましたトラブルスポットではありませんでした。私はこれが私に投げかけられている多くの変更のために過度に複雑にしてしまったと思うし、私は一緒にやり遂げる方法がたくさんある。 –

0

トーマスはKISS法と同じでした。私は大きな一歩を踏み出し、始まりました。

ここに私が思いついたのがあります。これは、日付+30について必要なことを行い、ファイルに書き戻します。私はこのメソッドがより洗練されていると思うし、私は他のテキストを機能を通してマッサージすることができます。

この新しいスクリプトに関するご質問は、 です:1.これは新しいファイルに書き込むことなく行うことができますか? 1ファイルに保存する方が簡単です。 2.ノードの複製と元のノードの削除を避け、元のノードの値を直接変更できますか? 3.私はその最後のノード<Status>をそれ自身の行にする方法を見逃しているようです。

スクリプト:

Dim xmlDoc: Set xmlDoc = CreateObject("Msxml2.DOMDocument") 
xmlDoc.Async = False 
xmlDoc.load "C:\Scripts\Run\MonVid-SHORT.xml" 

Dim xmldoc2: set xmldoc2 = CreateObject("Msxml2.DOMDocument") 
Dim strSkeleton : strSkeleton= "<?xml version=""1.0"" encoding=""utf-8""?>" & _ 
           "<XMLFeederRoot>" & _ 
           "</XMLFeederRoot>" 
xmldoc2.loadXML(strSkeleton) 
xmldoc2.save "C:\Scripts\Copy\New_MonVid-Short.xml" 
xmlDoc2.async = False 
xmlDoc2.load "C:\Scripts\Copy\New_MonVid-Short.xml" 
Dim sXPath : sXPath  = "/XMLFeederRoot/Ad[Start_Date=End_Date]" 


For Each n In XMLDoc.SelectNodes(sXpath) 
    set l = n.cloneNode(True) 
    q= l.selectSingleNode("/End_Date").text 

    strSDat=SplitArray(q) 

    l.removeChild(l.childNodes.item(2)) 
    set Stat= l.selectSingleNode("/Status") 
    set Parent= Stat.parentNode 
    set EDate= xmlDoc2.createElement("End_Date") 
    EDate.appendChild xmlDoc2.createTextNode(strSDat) 
    Parent.insertBefore EDate, Stat 

    xmldoc2.documentElement.appendChild parent 

Next 

xmlDoc2.save xmldoc2.url 


Function SplitArray(strval1) 
dim SplitArray1, SplitArray2, strSDat 

splitArray1 = split(strval1, "-") 
splitArray1(2) = left(splitArray1(2), 2) 
strDate1 = SplitArray1(1) & "/" & SplitArray1(2) & "/" & SplitArray1(0) 
strDate30 = DateAdd("d", 30, strDate1) 

SplitArray2 = split(strDate30, "/") 

'Add zero to the left 
If Len(SplitArray2(0))<2 Then 
    SplitArray2(0)= Right("0" & SplitArray2(0), 2) 
End If 
If Len(SplitArray2(1))<2 Then 
    SplitArray2(1)= Right("0" & SplitArray2(1), 2) 
End If 

SplitArray2(1) = splitArray2(1) & "T00:00:00" 
strSDat = SplitArray2(2) & "-" & SplitArray2(0) & "-" & SplitArray2(1) 
SplitArray= strSDat 

End Function 

出力ファイル:最も簡単な場合には

<?xml version="1.0" encoding="utf-8"?> 
<XMLFeederRoot><Ad> 
     <Ad_Number>d00524224</Ad_Number> 
     <Start_Date>2016-08-20T00:00:00</Start_Date> 
     <End_Date>2016-09-19T00:00:00</End_Date><Status>Run</Status> 
    </Ad><Ad> 
     <Ad_Number>d00524225</Ad_Number> 
     <Start_Date>2016-08-20T00:00:00</Start_Date> 
     <End_Date>2016-09-19T00:00:00</End_Date><Status>Run</Status> 
    </Ad> 
</XMLFeederRoot> 
関連する問題