重新格式化 XML 文件的脚本
Posted
技术标签:
【中文标题】重新格式化 XML 文件的脚本【英文标题】:Script to reformat XML file 【发布时间】:2011-02-10 16:55:44 【问题描述】:我正在尝试将 XML 文件从一种格式更改为另一种格式,但不知道如何为其编写脚本。有人可以帮忙吗? 源文件如下所示:
<Record>
<FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
<FieldValue fieldName="periode" fieldValue="2009-23-31" fieldValueIsNull="false" fieldValueNatural="2009-10-31 00:23:23"/>
<FieldValue fieldName="formulierid" fieldValue="9001HK1V10" fieldValueIsNull="false" fieldValueNatural="9001HK1V10"/>
<FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
<FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
<FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
<FieldValue fieldName="value" fieldValue="5F" fieldValueIsNull="false" fieldValueNatural="5F"/>
<FieldValue fieldName="post_value" fieldValue="0.00" fieldValueIsNull="false" fieldValueNatural="1.037E-4"/>
<FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
<FieldValue fieldName="rij" fieldValue="r_24_100_1_000_0" fieldValueIsNull="false" fieldValueNatural="r_24_100_1_000_0"/>
<FieldValue fieldName="kolom" fieldValue="c_2250_SPU" fieldValueIsNull="false" fieldValueNatural="c_2250_SPU"/>
</Record>
<Record>
<FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
<FieldValue fieldName="periode" fieldValue="2009-23-31" fieldValueIsNull="false" fieldValueNatural="2009-10-31 00:23:23"/>
<FieldValue fieldName="formulierid" fieldValue="9001HK1V10" fieldValueIsNull="false" fieldValueNatural="9001HK1V10"/>
<FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
<FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
<FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
<FieldValue fieldName="value" fieldValue="5F" fieldValueIsNull="false" fieldValueNatural="5F"/>
<FieldValue fieldName="post_value" fieldValue="0.00" fieldValueIsNull="false" fieldValueNatural="1.037E-4"/>
<FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
<FieldValue fieldName="rij" fieldValue="r_24_108_0_000_0" fieldValueIsNull="false" fieldValueNatural="r_24_108_0_000_0"/>
<FieldValue fieldName="kolom" fieldValue="c_2250_SPU" fieldValueIsNull="false" fieldValueNatural="c_2250_SPU"/>
</Record>
<Record>
<FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
<FieldValue fieldName="periode" fieldValue="2009-23-31" fieldValueIsNull="false" fieldValueNatural="2009-10-31 00:23:23"/>
<FieldValue fieldName="formulierid" fieldValue="9001HK1V10" fieldValueIsNull="false" fieldValueNatural="9001HK1V10"/>
<FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
<FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
<FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
<FieldValue fieldName="value" fieldValue="5F" fieldValueIsNull="false" fieldValueNatural="5F"/>
<FieldValue fieldName="post_value" fieldValue="0.00" fieldValueIsNull="false" fieldValueNatural="1.6049E-4"/>
<FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
<FieldValue fieldName="rij" fieldValue="r_06_000_1_010_0" fieldValueIsNull="false" fieldValueNatural="r_06_000_1_010_0"/>
<FieldValue fieldName="kolom" fieldValue="c_2250_SPU" fieldValueIsNull="false" fieldValueNatural="c_2250_SPU"/>
</Record>
这是我需要的格式:
<bestand registratienummer="123">
<rapportage nihil="false" periode="2009-23-31" formulierid="9001HK1V10" versie="1" frequentie="M">
<variant type="Landen" value="5F" />
<post value="0.00" cube="c01" rij="r_24_100_1_000_0" kolom="c_2250_SPU" />
</rapportage>
<rapportage nihil="false" periode="2009-23-31" formulierid="9001HK1V10" versie="1" frequentie="M">
<variant type="Landen" value="5F" />
<post value="0.00" cube="c01" rij="r_24_108_0_000_0" kolom="c_2250_SPU" />
</rapportage>
<rapportage nihil="false" periode="2009-23-31" formulierid="9001HK1V10" versie="1" frequentie="M">
<variant type="Landen" value="5F" />
<post value="0.00" cube="c01" rij="r_06_000_1_010_0" kolom="c_2250_SPU" />
</rapportage>
</bestand>
非常感谢!
【问题讨论】:
【参考方案1】:XSLT 正是为此目的而设计的。您可以将任何定义明确的 XML 文件转换为任何其他纯文本格式,包括不同的 XML 结构。获取例如xsltproc,写一个脚本就完成了。
如果您需要先学习 XSLT,这里是一个很好的起点:http://www.w3schools.com/xsl/(本教程提供了转换为 Xhtml 的示例,但您只需要使用目标 XML 标记而不是 XHTML 标记...)。
这可能是一个很好的开始脚本(抱歉,我没有时间在这里给你一个完整的脚本):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" encoding="utf-8" />
<xsl:template match="/">
<bestand registratienummer="123">
<apply-templates select="//Record"/>
</bestand>
</xsl:template>
<xsl:template match="Record">
<xsl:variable name="nihil" select="FieldValue[@fieldName='rapportage_nihil']/@fieldValue"/>
<!-- add more variable lookups here. you need XPath for that. -->
<rapportage nihil="$nihil" periode="$periode">
<!-- add more output here -->
</rapportage>
</xsl:template>
</xsl:stylesheet>
你可以给xsltproc这个样式表和你的源XML文档,它会给你新的XML文件。也许您需要确保源 XML 文件定义明确,即包含 one 根元素。您的示例看起来没有,您可能需要用任意元素包围它。
详细介绍一下 XSLT 和脚本:假设您有两个指针。一个在 XSLT 脚本中,一个在您的 XML 源文件中。 XSLT 是关于“应用模板”的,它总是使用最接近匹配的模板(将模板视为某种功能)。
首先,最接近的匹配项是根元素,因此 XSLT 指针将在模板中以match="/"
开头。 XML 指针位于 XML 源文档的根元素(别名“tag”)中。任何以xsl:
开头的非元素都将被视为输出元素。因此,首先,xsltproc 将输出<bestand>
元素。
然后 XSLT 指针更进一步,找到<apply-templates>
选择与//Record
匹配的所有元素(双斜线表示“在任何深度”)。对于每个<Record>
元素,它将“调用”匹配的模板。这里最接近的匹配是<xsl:template match="Record">
。
所以 XSLT 指针会跳转到模板,XML 指针会跳转到第一个 <Record>
。然后声明一个变量 (nihil
),其中包含来自使用 XPath 表达式在源文档的 XML 结构中更深入地选择从 XML 指针开始的记录中的一些信息。 XPath 表达式说:“从元素FieldValue
中选择属性fieldName
和值'rapportage_nihil'
属性值fieldValue
”(把它想象成XML 数据的SQL WHERE 子句;属性是此处以 @
为前缀)。
您需要复制、粘贴和更改输出文档中所需的每条信息该行。然后评估输出元素<rapportage>
,用<xsl:variable>
替换上面设置的每个变量(例如$nihil
)。您需要以与<rapportage>
元素相同的方式在<rapportage>
元素中添加元素。然后模板结束,下一个<Record>
将通过模板。
【讨论】:
非常感谢您的帮助!我不知道如何编写 XSLT 脚本,但我会看看是否可以修改您的示例。 我试着看看我是否能理解你的脚本在做什么,但很抱歉,我不知道如何处理它。感谢您的时间。其他人可以帮助编写脚本吗? @JonS:好的,我已经添加了一些关于脚本如何工作的解释,但是从这里开始,我认为您需要自己进行试验,阅读您如何使用 XSLT 和 xsltproc 或任何其他 XSLT处理器(xsltproc 是一个命令行实用程序,没有图形界面)。或者,如果您没有时间学习 XSL(T),您可能不得不花钱请人来编写脚本。 maligree - 我修改了您的脚本,遇到了一些问题,但能够在一些帮助下克服它们并创建我需要的文件。你的解释也很有帮助。非常感谢! @JonS:那么请将答案标记为正确。这就是 ***.com 的工作方式 :) 感谢您报告我实际上可以帮助您 :)以上是关于重新格式化 XML 文件的脚本的主要内容,如果未能解决你的问题,请参考以下文章