假设我有以下XML:
<DataDictionary numberOfFields="5">
<DataField name="Species" optype="categorical" dataType="string">
<Value value="setosa"/>
<Value value="versicolor"/>
<Value value="virginica"/>
</DataField>
<DataField name="Sepal.Length" optype="continuous" dataType="double"/>
<DataField name="Sepal.Width" optype="continuous" dataType="double"/>
<DataField name="Petal.Length" optype="continuous" dataType="double"/>
<DataField name="Petal.Width" optype="continuous" dataType="double"/>
</DataDictionary>
Run Code Online (Sandbox Code Playgroud)
有人可以为所有属性名称提供正则表达式(例如vim或sed)吗?
例如,我想numberOfFields
是NumberOfFields
和dataType
是DataType
.
使用sed处理XML通常不是一个好主意,因为sed以基于行的方式工作,而XML并不真正关心换行符.例如,你可以拥有
<foo bar=
"baz"/>
Run Code Online (Sandbox Code Playgroud)
在完全有效的XML中,使用sed(或其他纯文本工具)很难处理.
我建议使用XSLT样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:variable name="vLower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:variable name="capname"
select="concat(translate(substring(name(.),1,1), $vLower, $vUpper), substring(name(.), 2))"/>
<xsl:attribute name="{$capname}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
比如把它放在一个文件中,foo.xsl
然后使用XSLT处理器xsltproc
来运行它:
xsltproc foo.xsl foo.xml
Run Code Online (Sandbox Code Playgroud)
foo.xml
你的XML文件在哪里.或者,用xalan
:
xalan -xsl foo.xsl -in foo.xml
Run Code Online (Sandbox Code Playgroud)
任何XSLT处理器都可以; 对于其他人,请检查他们的联机帮助
其工作原理如下:
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
是适用于所有节点的身份转换(在这种情况下不是属性,因为它们在别处处理)并递归地应用模板.这使得转换的输出是输入的副本,其中没有其他模板适用.肉在里面
<xsl:variable name="vLower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:template match="@*">
<xsl:variable name="capname"
select="concat(translate(substring(name(.),1,1), $vLower, $vUpper), substring(name(.), 2))"/>
<xsl:attribute name="{$capname}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
这适用于所有属性(@*
).
concat(translate(substring(name(.),1,1), $vLower, $vUpper), substring(name(.), 2))
Run Code Online (Sandbox Code Playgroud)
是属性名称的大写版本,并将其分配给变量capname
.然后
<xsl:attribute name="{$capname}">
<xsl:value-of select="."/>
</xsl:attribute>
Run Code Online (Sandbox Code Playgroud)
插入具有该大写名称的新属性和旧值以代替旧的非大写属性.
这将适用于所有有效的XML输入.