【问题标题】:reformat an xml file重新格式化 xml 文件
【发布时间】:2016-08-26 12:51:51
【问题描述】:

我有以下 xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
    <Data xmlns="http://www.test.com">
        <form Name="Group1">
            <Period Time="19042016T08:35:00"/>
            <Type c="1">Load</Type>
            <Type c="2">Memory</Type>
            <Type c="3">CPU</Type>
            <Type c="4">Task</Type>
            <Value Item="M-1">
                <val c="1">2979</val>
                <val c="2">0</val>
                <val c="3">9599</val>
                <val c="4">0</val>
            </Value>
            <Value Item="M-2">
                <val c="1">2973</val>
                <val c="2">0</val>
                <val c="3">0</val>
                <val c="4">0</val>
            </Value>
            <Value Item="M-3">
                <val c="1">2985</val>
                <val c="2">11889</val>
                <val c="3">0</val>
                <val c="4">0</val>
            </Value>
            <Value Item="M-4">
                <val c="1">28</val>
                <val c="2">0</val>
                <val c="3">0</val>
                <val c="4">2980</val>
            </Value>
        </form>
        <form Name="Group2">
            <Period Time="19042016T08:35:00"/>
            <Type c="1">Process</Type>
            <Type c="2">User</Type>
            <Type c="3">command</Type>
            <Type c="4">priority</Type>
            <Value Item="M-1">
                <val c="1">0</val>
                <val c="2">0</val>
                <val c="3">0</val>
                <val c="4">4477</val>
            </Value>
            <Value Item="M-2">
                <val c="1">0</val>
                <val c="2">0</val>
                <val c="3">0</val>
                <val c="4">4540</val>
            </Value>
            <Value Item="M-3">
                <val c="1">0</val>
                <val c="2">0</val>
                <val c="3">0</val>
                <val c="4">4526</val>
            </Value>
            <Value Item="M-4">
                <val c="1">0</val>
                <val c="2">0</val>
                <val c="3">0</val>
                <val c="4">4445</val>
            </Value>
        </form>
    </Data>

我想得到如下输出:

Group=Group1, Time=19042016T08:35:00    
             M-1        M-2         M-3         M-4     
Load        2979       2973        2985          28
Memory         0          0       11889           0
CPU         9599          0           0           0
Task           0          0           0        2980

Name=Group2, Time=19042016T08:35:00    
             M-1        M-2         M-3         M-4     
Process        0          0           0           0
User           0          0           0           0
command        0          0           0           0
priority    4477       4540        4445        4445  

通过查看此处建议的一些 xsltproc 示例。我想出了以下样式表。

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:t="http://www.test.com">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/t:Data">
        <xsl:for-each select="t:form">
            <xsl:value-of select="concat('Group=', @Name, ', Time=',t:Period/@Time,'&#xA;')"/>
            <xsl:for-each select="t:Type">
                <xsl:value-of select="concat('CounterName=', text(), '&#xA;')"/>
            </xsl:for-each>
            <xsl:for-each select="t:Value">
                <xsl:value-of select="concat('Machine=', @Item, '&#xA;')"/>
                <xsl:for-each select="t:val">
                    <xsl:value-of select="concat('CounterValue=', text(), '&#xA;')"/>
                </xsl:for-each>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

那么结果如下:

xsltproc.exe tx.xsl data.xml 
Group=Group1, Time=19042016T08:35:00
CounterName=Load
CounterName=Memory
CounterName=CPU
CounterName=Task
Machine=M-1
CounterValue=2979
CounterValue=0
CounterValue=9599
CounterValue=0
Machine=M-2
CounterValue=2973
CounterValue=0
CounterValue=0
CounterValue=0
Machine=M-3
CounterValue=2985
CounterValue=11889
CounterValue=0
CounterValue=0
Machine=M-4
CounterValue=28
CounterValue=0
CounterValue=0
CounterValue=2980
Group=Group2, Time=19042016T08:35:00
CounterName=Process
CounterName=User
CounterName=command
CounterName=priority
Machine=M-1
CounterValue=0
CounterValue=0
CounterValue=0
CounterValue=4477
Machine=M-2
CounterValue=0
CounterValue=0
CounterValue=0
CounterValue=4540
Machine=M-3
CounterValue=0
CounterValue=0
CounterValue=0
CounterValue=4526
Machine=M-4
CounterValue=0
CounterValue=0
CounterValue=0
CounterValue=4445

有谁知道我如何从 xsltproc 的结果中获得上述所需的输出。是否可以使用不同的样式表完成,或者我需要在当前样式表的结果之后应用后处理脚本?

非常感谢。

【问题讨论】:

  • 您可以使用 XSLT 1.0 吗?喜欢xsltproc
  • 最好的照片是 xslt 文件,使用 xsltproc 处理
  • 我没有 xsltproc,得到了这个 -bash: xsltproc: command not found,很遗憾我不能在这台机器上安装任何额外的工具。
  • 你安装python了吗?
  • 是的,python 已安装。我以前从未使用过 python :-(

标签: xml bash xslt awk


【解决方案1】:

假设您希望每个 form 都有一个制表符分隔的“表格”,请尝试以下样式表:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:t="http://www.test.com">
<xsl:output method="text"/>

<xsl:template match="/t:Data">
    <xsl:for-each select="t:form">
        <!-- table header -->
        <xsl:text>Name=</xsl:text>
        <xsl:value-of select="@Name"/>
        <xsl:text>, Time=</xsl:text>
        <xsl:value-of select="t:Period/@Time"/>
        <xsl:text>&#10;&#10;</xsl:text>
        <!-- column headers -->
        <xsl:for-each select="t:Value">
            <xsl:text>&#9;</xsl:text>
            <xsl:value-of select="@Item"/>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
        <!-- rows -->
        <xsl:for-each select="t:Type">
            <xsl:variable name="i" select="position()" />
            <!-- row header -->
            <xsl:value-of select="."/>
            <!-- row values -->
            <xsl:for-each select="../t:Value">
                <xsl:text>&#9;</xsl:text>
                <xsl:value-of select="t:val[$i]"/>
            </xsl:for-each>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入的结果将是:

Name=Group1, Time=19042016T08:35:00

    M-1 M-2 M-3 M-4
Load    2979    2973    2985    28
Memory  0   0   11889   0
CPU 9599    0   0   0
Task    0   0   0   2980

Name=Group2, Time=19042016T08:35:00

    M-1 M-2 M-3 M-4
Process 0   0   0   0
User    0   0   0   0
command 0   0   0   0
priority    4477    4540    4526    4445

如果有适当的制表符间距(此处:每个制表符 10 个空格),它将如下所示:

【讨论】:

  • 嗨,迈克尔。我从您的提案中得到以下输出。 xsltproc.exe ty.xsl data.xml 名称=Group1,时间=19042016T08:35:00 M-1 M-2 M-3 M-4 加载 2979 2973 2985 28 内存 0 0 11889 0 CPU 9599 0 0 0 任务 0 0 0 2980 名称=Group2,时间=19042016T08:35:00 M-1 M-2 M-3 M-4 进程0 0 0 0 用户0 0 0 0 命令0 0 0 0 优先级4477 4540 4526 4445
  • @CarlosL 请不要在 cmets 中发布代码。我已将我的代码获得的结果添加到我的答案中。如果您需要其他内容,请编辑您的问题并在此处澄清。
  • xsltproc.exe ty.xsl data.xml 名称=Group2,时间=19042016T08:35:00 M-1 M-2 M-3 M-4 进程 0 0 0 0 用户 0 0 0 0命令 0 0 0 0 优先级 4477 4540 4526 4445 是否可以捕获类型的长度并在格式化之前使用它以避免在优先级的最后一行发生什么?感谢您的帮助。
  • 得到了答案,非常感谢,感谢您的帮助。
猜你喜欢
  • 2011-02-10
  • 2013-11-12
  • 2020-10-28
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
相关资源
最近更新 更多