2016-01-20 119 views
-1

我试图找到一种方法,基于XML文件输入在Windows中创建完整文件夹/子文件夹/文件(快捷方式)树状图。Windows:基于XML文件创建文件夹结构

我的XML看起来是这样的:

<folder name="Folder1"> 
    <shortcut url="http://A.com" name="A" /> 
    <shortcut url="http://B.com" name="B" /> 
    <folder name="1.1"> 
     <shortcut url="http://C.com" name="C" /> 
    </folder> 
    <folder name="Folder1.2"> 
     <shortcut url="http://D.com" name="D" /> 
    </folder> 
</folder> 
<folder name="Folder2"> 
    ... 
</folder> 

并将得到的文件夹为:

  • Folder1中
    • A.url
    • B.url
    • Folder1中。 1
      • C.url
    • Folder1.2
      • D.url
  • 文件夹2
    • ...

- >综上所述,递归文件夹/子文件夹的创建,再加上快捷方式(的.url文件)的创建

如何做到这一点任何想法? 通过cmd,powershell?

(如果在的.url无法创建文件,我将手动让他们(超过300 ...))

非常感谢!


编辑:解

感谢@rojo,良好的方向发展。 我修改了html文件创建“快捷方式”的需求。 (内容截断,仅供示例) 我添加了一个目标路径,几个错误处理(创建文件夹和文件,创建错误txt文件,易于搜索以手动修复),以及在根目录下创建文件。 (不是在子文件夹)

可能不是很优化,但也...

<# : Batch Portion 
@echo off & setlocal 

powershell -noprofile -noexit -noninteractive "iex (gc \"%~f0\" | out-string)" 
goto :EOF 

: End Batch/begin PowerShell hybrid chimera #> 

[xml]$DOM = gc clv.xml 
$destPath="D:\Test\Folders" 

function CreateShortcut([string]$target, [string]$saveLoc, [string]$fileName) { 

$aspxText= @" 
<html> 
<body> 
<a href="$target">Target URL</a> 
</form> 
</body> 
</html> 
"@ 
try{ 
New-Item ($saveLoc+'/'+$fileName+'.aspx') -type file -value $aspxText -ea Stop 
} 
catch{ 
[email protected]" 
Name: 
$fileName 
Url: 
$target 

Error: 
$_.Exception.GetType().FUllname 
"@ 

New-Item ($saveLoc+'/###Error.txt') -type file -value $txtDoc 
} 

    write-host "$($saveLoc)\$($fileName)" -f cyan 
} 

cd $destPath 
function launchCreation($root){ 
    $rootshortcuts = @($root.shortcut) 
    if($rootshortcuts -ne $null){ 
     foreach ($shortcut in $rootshortcuts) { 
      $fixedShortcutName=$shortcut.name -replace '[<>:"\/\\?\*\|]', '-' 
      $urlfile = (pwd).Path 
      CreateShortcut $shortcut.url $urlfile $fixedShortcutName $shortcut.isDoc $shortcut.isTaxo 
     } 
    } 
    Walk($root) 
} 
function Walk($root) { 
    $folders = @($root.folder) 
    if($folders -ne $null){ 
     foreach ($folder in $folders) { 
      $folderName=$folder.name -replace '[<>:"\/\\?\*\|]', '-' 
      if (-not (test-path $folderName)) { md $folderName } 
      cd $folderName 
      write-host (Join-Path $destPath $folderName) -f magenta 
      $shortcuts = @($folder.shortcut) 
      if($shortcuts -ne $null){ 
       foreach ($shortcut in $shortcuts) { 
        $fixedShortcutName=$shortcut.name -replace '[<>:"\/\\?\*\|]', '-' 
        $urlfile = (pwd).Path 
        CreateShortcut $shortcut.url $urlfile $fixedShortcutName $shortcut.isDoc $shortcut.isTaxo 
       } 
      } 
      Walk $folder 
      cd.. 
     } 
    } 

} 

[void](launchCreation $DOM.documentElement) 
+0

使用PowerShell(PowerGUI的为典型),如果你知道C#或使用Excel VBA(就像VB6 IDE运行和调试.NET类)如果你现在用vb6 – SalientBrain

+5

用脚本很简单。我会使用powershell,但这更多的是个人喜好。使用你知道的或你想学的东西。我会建议搜索“powershell xml”和cmdlet“new-item”。如果您遇到问题,请在此处询问,我们会提供帮助,但在这一点上,问题太广泛了。更多的请求/订单,而不是QA问题。 –

+0

用基于rojo的有用答案的代码编辑我的问题。 – okp

回答

1

接受了挑战,但仅仅是为了阻止他人试图将XML解析为扁平文本以进行标记和刮取。将来,请努力编写自己的代码,并在寻求帮助时发布你写的内容。

我掀起一个快速和肮脏的PowerShell脚本,做你想做的。它将XML作为XML对象导入,然后递归地遍历DOM,创建不存在的目录并创建快捷方式。 XML 必须格式良好,才能正常工作。

这是我用来测试脚本中的XML:

<?xml version="1.0"?> 
<root> 
    <folder name="Folder1"> 
     <shortcut url="http://A.com" name="A" /> 
     <shortcut url="http://B.com" name="B" /> 
     <folder name="1.1"> 
      <shortcut url="http://C.com" name="C" /> 
     </folder> 
     <folder name="Folder1.2"> 
      <shortcut url="http://D.com" name="D" /> 
     </folder> 
    </folder> 
    <folder name="Folder2"> 
     <shortcut url="http://E.com" name="E" /> 
    </folder> 
</root> 

而这里的.PS1脚本:

[xml]$DOM = gc folders.xml 
$shell = New-Object -COM WScript.Shell 

function CreateShortcut([string]$target, [string]$saveLoc) { 
    $shortcut = $shell.CreateShortcut($saveLoc + ".url") 
    $shortcut.TargetPath = $target 
    $shortcut.Save() 
    write-host $shortcut.FullName -f cyan 
} 

function Walk($root) { 
    foreach ($folder in $root.folder) { 
     if (-not (test-path $folder.name)) { md $folder.name } 
     cd $folder.name 
     write-host (pwd).Path -f magenta 
     foreach ($shortcut in $folder.shortcut) { 
      $urlfile = ((pwd).Path, $shortcut.name) -join '\' 
      CreateShortcut $shortcut.url $urlfile 
     } 
     Walk $folder 
     cd .. 
    } 
} 

[void](Walk $DOM.documentElement) 

如果你宁愿有一个蝙蝠脚本,只需插入这个注释块进入脚本的顶部,并给这个东西一个.bat扩展名:

<# : Batch Portion 
@echo off & setlocal 

powershell -noprofile -noninteractive "iex (gc \"%~f0\" | out-string)" 
goto :EOF 

: End Batch/begin PowerShell hybrid chimera #> 
+0

非常感谢!很高兴有一个真正的XMl解析器,而不是依靠换行符!它指向我正确的方向,但我打破了这一切......请看看我编辑的问题与代码 – okp

+0

循环无限期...看起来像循环在非现有的节点上... – okp

-1
@ECHO Off 
SETLOCAL 
SET "sourcedir=U:\sourcedir" 
SET "destdir=U:\destdir" 
SET "filename1=%sourcedir%\q3489447.txt" 
PUSHD "%destdir%" 
FOR /f "usebackqtokens=*" %%z IN ("%filename1%") DO (
FOR /f "tokens=1-6delims=<=>" %%a IN ('echo "%%z"') DO (
    IF "%%~b"=="shortcut url" CALL :mdshortcut %%d 
    IF "%%~b"=="folder name" MD "%%c"&CD "%%c" 
    IF "%%~b"=="/folder" CD .. 
) 
) 
POPD 

GOTO :EOF 

:mdshortcut 
MD "%~1.url" 
GOTO :EOF 

你需要改变的sourcedirdestdir设置以适合你的情况。

我用了一个名为q3489447.txt的文件来存放我的测试数据。

  • 到目标目录
  • 读取文件;剥离前导空格使用合适的分隔符%%z
  • ,打破行成份
  • 如果第二部分folder name然后创建新的目录,并改变它
  • 如果第二部分是/folder回来一个目录级。
  • 如果第二部分是shortcut url,则调用通过第四部分的子例程,其第一部分是附加.url的所需新目录名称。
  • 回到原来的目录成品

时,你可以追加2>nulmd命令来抑制一个目录已经存在的投诉。

+0

那么没有捷径? –

+0

没有好行为不受惩罚,是吧? – rojo

0

这种类型的问题很容易通过递归过程解决。以下解决方案只需显示md & cd创建文件夹结构所需的命令;如果结果看起来正确,则从每个命令中删除ECHO部分。我希望这种方法很简单,所以不需要解释。

@echo off 
setlocal EnableDelayedExpansion 

call :treeProcess < input.xml 
goto :EOF 


:treeProcess 
    set "line=:EOF" 
    set /P "line=" 
    for /F "tokens=1-5 delims=<=> " %%a in ("%line%") do (
     if "%%a" equ "folder" (
     ECHO md "%%~c" 
     ECHO cd "%%~c" 
     call :treeProcess 
    ) else if "%%a" equ "shortcut" (
     echo Create here "%%~e.url" 
    ) else if "%%a" equ "/folder" (
     ECHO cd .. 
     exit /B 
    ) 
    ) 
if "%line%" neq ":EOF" goto treeProcess 
exit /B 

这是输出与输入提供:

md "Folder1" 
cd "Folder1" 
Create here "A.url" 
Create here "B.url" 
md "1.1" 
cd "1.1" 
Create here "C.url" 
cd .. 
md "Folder1.2" 
cd "Folder1.2" 
Create here "D.url" 
cd .. 
cd .. 
md "Folder2" 
cd "Folder2" 
cd ..