为什么XMLStarlet将字符串中的">"替换为">"?



XMLStarlet编辑器:

xmlstarlet ed -O -u "/include/X-PRE-PROCESS[@cmd='set' and starts-with(@data,'domain=')]/@data" -v 'domain=test.domain' vars.xml

在目标文件上:

<include>
    <X-PRE-PROCESS cmd="set" data="domain=domain.com"/>
    <X-PRE-PROCESS cmd="set" data="bong-ring=v=-7;%(100,0,941.0,1477.0);v=-7;>=2;+=.1;%(1400,0,350,440)"/>
</include>

改变必要的data="domain=domain.com"值,
但也返回意想不到的(对我来说)改变>&gt;在字符串值bong-ring=...,所以>=2成为&gt;=2

<include>
    <X-PRE-PROCESS cmd="set" data="domain=test.domain"/>
    <X-PRE-PROCESS cmd="set" data="bong-ring=v=-7;%(100,0,941.0,1477.0);v=-7;&gt;=2;+=.1;%(1400,0,350,440)"/>
</include>

">"不受引号""保护吗?

所以问题是:

XMLStarlet是否有错误,或者是应用程序(Freeswitch v1.7)中使用vars.xml并将
<X-PRE-PROCESS cmd="set" data="bong-ring=v=-7;%(100,0,941.0,1477.0);v=-7;&gt;=2;+=.1;%(1400,0,350,440)"/>
解析为
v=-7;%(100,0,941.0,1477.0);v=-7;&gt;=2;+=.1;%(1400,0,350,440)

XMLStarlet这样做没有错。

>被引号"保护"的概念是错误的。从技术上讲,>在属性值中是合法的,而<在文本节点值中是非法的(>也是如此)。

通常,无论上下文(*),工具都会转义xml保留字符,因此文本节点将包含&gt;,属性也将包含&gt;。这没什么问题。

然而,本质上,属性值或文本节点值中的每个字符都可以被转义。

以下是完全合法的XML, 100%等同于您的两个示例:

<include>
    <X-PRE-PROCESS cmd="&#x73;&#x65;&#x74;" data="&#x64;&#x6f;&#x6d;&#x61;&#x69;&#x6e;&#x3d;&#x74;&#x65;&#x73;&#x74;&#x2e;&#x64;&#x6f;&#x6d;&#x61;&#x69;&#x6e;"/>
    <X-PRE-PROCESS cmd="&#x73;&#x65;&#x74;" data="&#x62;&#x6f;&#x6e;&#x67;&#x2d;&#x72;&#x69;&#x6e;&#x67;&#x3d;&#x76;&#x3d;&#x2d;&#x37;&#x3b;&#x25;&#x28;&#x31;&#x30;&#x30;&#x2c;&#x30;&#x2c;&#x39;&#x34;&#x31;&#x2e;&#x30;&#x2c;&#x31;&#x34;&#x37;&#x37;&#x2e;&#x30;&#x29;&#x3b;&#x76;&#x3d;&#x2d;&#x37;&#x3b;&#x3e;&#x3d;&#x32;&#x3b;&#x2b;&#x3d;&#x2e;&#x31;&#x3b;&#x25;&#x28;&#x31;&#x34;&#x30;&#x30;&#x2c;&#x30;&#x2c;&#x33;&#x35;&#x30;&#x2c;&#x34;&#x34;&#x30;&#x29;"/>
</include>

可以归结为:XML不是字符串。不要把它当成一个。不要使用或创建将XML视为字符串的工具。XML需要一个解析器——在这种情况下,所有符合标准的解析器都会做正确的事情。


(*)从XML序列化器的角度来看:a)为属性值和文本节点生成不同的输出使序列化过程更加复杂,而无需向结果添加任何值。b)编写一个函数对任何字符串进行xml转义,然后重用它会更容易。c)对称通常更容易处理,程序员倾向于喜欢它。

最新更新