XMLStarlet不打印全行

时间:2014-12-20 16:06:36

标签: xml batch-file

我的批次有问题。 XMLStarlet没有向我显示完整的行。

但是,我只使用下面的批处理文件3DS,并且未显示该行的其余部分。

输出应该只是来自XML文件中包含 3DS 的第一个title标记行的版本信息,例如 9.4.0-21 没有 3DS

我对任何答案都很满意。

我的批处理文件:

@echo off
cls
echo.
echo.
echo ----------- Nintendo 3DS Firmware Checker --------------------------------------
echo --------------------- A CMD based Tool -----------------------------------------
echo.
echo.
echo.
httpget http://yls8.mtheall.com/ninupdates/feed.php nintendo3dsupdate.xml
for /f %%i in ('XML.EXE sel -t -v "//channel/item/title" "nintendo3dsupdate.xml"') do set "var111=%%i" >nul
echo.
echo.
echo                "%var111%" is the currently 3ds firmware.
echo.
echo.
pause
exit

XML文件的内容 nintendo3dsupdate.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
    <channel>
      <title>Sysupdate Reports</title>
      <atom:link href="http://yls8.mtheall.com/ninupdates/feed.php" rel="self" type="application/rss+xml" />
      <link>http://yls8.mtheall.com/ninupdates/reports.php</link>
      <description>Nintendo System Update Reports</description>
      <lastBuildDate>Thu, 11 Dec 2014 23:05:04 +0000</lastBuildDate>
      <language>en</language>
      <sy:updatePeriod>hourly</sy:updatePeriod>
      <sy:updateFrequency>1</sy:updateFrequency>
        <item>
        <title>3DS 9.4.0-21</title>
        <link><![CDATA[http://yls8.mtheall.com/ninupdates/reports.php?date=12-11-14_07-05-04&sys=ctr]]></link>
        <guid isPermaLink="true"><![CDATA[http://yls8.mtheall.com/ninupdates/reports.php?date=12-11-14_07-05-04&sys=ctr]]></guid>
        <description>3DS 9.4.0-21</description>
        <pubDate>Thu, 11 Dec 2014 23:05:04 +0000</pubDate>
    </item>
    <item>
        <title>3DS 9.3.0-21 (stage5)</title>
        <link><![CDATA[http://yls8.mtheall.com/ninupdates/reports.php?date=12-08-14_07-45-04&sys=ctr]]></link>
        <guid isPermaLink="true"><![CDATA[http://yls8.mtheall.com/ninupdates/reports.php?date=12-08-14_07-45-04&sys=ctr]]></guid>
        <description>3DS 9.3.0-21 (stage5)</description>
        <pubDate>Mon, 08 Dec 2014 23:45:03 +0000</pubDate>
    </item>
    <item>
        <title>3DS 9.3.0-21 (stage4)</title>
        <link><![CDATA[http://yls8.mtheall.com/ninupdates/reports.php?date=12-08-14_07-35-04&sys=ctr]]></link>
        <guid isPermaLink="true"><![CDATA[http://yls8.mtheall.com/ninupdates/reports.php?date=12-08-14_07-35-04&sys=ctr]]></guid>
        <description>3DS 9.3.0-21 (stage4)</description>
        <pubDate>Mon, 08 Dec 2014 23:35:03 +0000</pubDate>
    </item>
    <item>
        <title>3DS 9.3.0-21 (stage3)</title>
        <link><![CDATA[http://yls8.mtheall.com/ninupdates/reports.php?date=12-08-14_07-25-04&sys=ctr]]></link>
        <guid isPermaLink="true"><![CDATA[http://yls8.mtheall.com/ninupdates/reports.php?date=12-08-14_07-25-04&sys=ctr]]></guid>
        <description>3DS 9.3.0-21 (stage3)</description>
        <pubDate>Mon, 08 Dec 2014 23:25:04 +0000</pubDate>
    </item>
 </channel>
</rss>

缩进具有水平制表符。 <title>3DS 9.4.0-21</title>还有2个标签。

1 个答案:

答案 0 :(得分:0)

以下是从XML文件中以 3DS 开头的第一个标题标记获取版本信息的批处理代码:

@echo off
cls
echo.
echo.
echo ----------- Nintendo 3DS Firmware Checker --------------------------------------
echo --------------------- A CMD based Tool -----------------------------------------
echo.
echo.
echo.
del "%TEMP%\nintendo3dsupdate.xml">nul 2>nul
set FirmwareVersion3DS=
httpget http://yls8.mtheall.com/ninupdates/feed.php "%TEMP%\nintendo3dsupdate.xml"
for /F "usebackq tokens=3 delims=< " %%V in (`%SystemRoot%\System32\findstr.exe "<title>3DS" "%TEMP%\nintendo3dsupdate.xml" 2^>nul`) do (
    set "FirmwareVersion3DS=%%V"
    goto OutputInfo
)
echo Failed to determine version of 3DS firmware!
echo.
goto :EndBatch

:OutputInfo
echo.
echo.
echo                "%FirmwareVersion3DS%" is the current 3DS firmware.
echo.
echo.
set FirmwareVersion3DS=

:EndBatch
del "%TEMP%\nintendo3dsupdate.xml">nul 2>nul
pause

首先通过命令findstr解析XML文件,搜索返回的简单文本字符串<title>3DS

        <title>3DS 9.4.0-21</title>
        <title>3DS 9.3.0-21 (stage5)</title>
        <title>3DS 9.3.0-21 (stage4)</title>
        <title>3DS 9.3.0-21 (stage3)</title>

每个用2个标签缩进的4行直接重定向到命令for,命令{@ 3}}使用左尖括号和空格字符作为分隔符分割每一行。因此,第一行分为:

  • 令牌1:                (两个水平制表符)
  • 令牌2:title>3DS
  • 令牌3:9.4.0-21
  • 令牌4:/title>

由于只对版本号感兴趣,只需将令牌 3 分配给环境变量 FirmwareVersion3DS 旁边分配的循环变量 V 。< / p>

对于此任务,仅对具有版本信息的第一行感兴趣。因此,在处理命令 findstr 返回的第一行之后,通过跳转退出循环以输出找到的版本信息。

如果由于没有连接到Web服务器或XML文件中的语法在此期间发生更改而发生错误(如无XML文件),则输出错误消息而不是版本信息。

如果令牌3确实引用了版本信息,则不会进行检查。因此,如果例如服务器上的PHP脚本输出空格而不是制表符,则必须更新批处理文件代码以缩进行。

批处理代码在从服务器下载之前删除XML文件,以避免解析旧的XML文件。在退出批处理文件之前,还会删除XML文件和使用过的环境变量,只是为了保留干净的环境。


修改

命令 的行也可以是

for /F "usebackq tokens=2 delims=<   " %%V in (`%SystemRoot%\System32\findstr.exe "<title>3DS" "nintendo3dsupdate.xml" 2^>nul`) do (

delims=之后有3个字符:

  1. 一个尖括号<
  2. 水平制表符(不是浏览器显示的空格序列)
  3. 单个空格字符。
  4. 分隔符的顺序很重要,否则命令行解释器会因语法错误退出批处理脚本。

    此修改将忽略缩进选项卡。因此现在第一行被拆分为:

    • 令牌1:title>3DS
    • 令牌2:9.4.0-21
    • 令牌3:/title>

    令牌 2 而不是3现在包含要输出的感兴趣的字符串。

    这个解决方案比第一个更好,因为如果带有版本字符串的行用空格或制表符缩进或者根本没有缩进,则无关紧要。