【问题标题】:xsd:boolean element type accept "true" but not "True". How can I make it accept it?xsd:boolean 元素类型接受“true”但不接受“True”。我怎样才能让它接受它?
【发布时间】:2026-01-16 18:40:01
【问题描述】:

我正在使用 xmllint --schema 选项来验证我的 XML,看起来像这样

<XML>
<Active>True</Active>
</XML>

在我的架构文件中,我有以下描述 Active 元素的行。

<xsd:element name="Active" type="xs:boolean" />

当我运行 xmllint 时,我收到错误消息,上面写着

/tmp/schema_validation.xml:73: 元素 活动:模式有效性错误: 元素“活动”:“真”不是 原子类型的有效值 'xs:boolean'。

当我将 XML 更改为

<Active>true</Active>

然后错误信息消失。

所以,看起来 xsd:boolean 对 xmllint 来说都是小写的“真/假”,但不是“真/假”。我的问题是,我怎样才能让 xmllint 接受 xsd:boolean 类型的“真” ?或者我可以使用不同的工具来验证这个 XML?在这一点上,更改 XML 或架构不是我的选择。

谢谢!

【问题讨论】:

  • 如果更改源 XML 或架构不是一个选项,那么我建议通过将布尔值标准化为正确 XSD 有效值的转换来运行源 XML。
  • 我曾想过这样做,但我害怕修改恰好为“真”的值。例如,如果名为“Description”的元素恰好包含值“True”,那么我不希望将其转换为“true”。我认为没有任何方法可以知道要应用规范化的元素。
  • 你需要逆流而上:从源头停止生成无效的 XML。

标签: xml xsd boolean


【解决方案1】:

你不能。

根据XML Schema specification,布尔值是truefalseTrue 无效:

3.2.2.1 词法表示 定义为·boolean· 的数据类型的实例可以具有 遵循合法文字 {true, false, 1, 0}。 3.2.2.2 规范表示 布尔值的规范表示是 字面量 {true, false}。

如果您使用的工具确实根据 XML Schema 标准进行验证,那么您无法说服它接受 True 作为布尔值。

【讨论】:

  • 谢谢。很高兴知道绝对没有办法重新定义 xsd:boolean
  • 换一种说法——如果上游软件为定义为 XML Schema 布尔值的东西生成 True,那么它们实际上不是在生成 XML,而是恰好看起来相似的其他东西。他们的营销部门不应该声称他们使用 XML,因为他们现在已经否定了使用 XML 的意义——为了提高效率而重用通用解析器的能力。
  • 我会在这里与@Oskar 有所不同。有些工具声称可以生成 XML,但实际上并没有,因为它们生成的内容格式不正确。但是在这里,您似乎有上游软件可以生成 格式良好但根据其 XML Schema 无效的 XML。它仍然是 XML。他们只是不能声称它符合您正在使用的 XML 模式。
  • 关键是上游的生成器使用模式的非标准解释,这就是为什么 OP 需要一个接受相同非标准模式解释的 xmllint。
  • 其实1、0也是有效值。见:w3schools.com/xml/schema_dtypes_misc.asp
【解决方案2】:

xs:boolean 预定义了它接受的输入类型。如果你需要不同的东西,你必须定义你自己的枚举:

 <xs:simpleType name="my:boolean">
    <xs:restriction base="xs:string">
      <xs:enumeration value="True"/>
      <xs:enumeration value="False"/>
    </xs:restriction>
  </xs:simpleType>

【讨论】:

  • 谢谢!我会要求这样的东西成为架构的一部分,以便我现在可以解决这个问题。
【解决方案3】:

如果您使用的是 Linux,或者在 Windows 上安装了 cygwin,则可以通过一个简单的 sed 脚本运行输入 XML,该脚本将用 &lt;Active&gt;true&lt;/Active&gt; 替换 &lt;Active&gt;True&lt;/Active&gt;,如下所示:

cat <your XML file> | sed 'sX<Active>True</Active>X<Active>true</Active>X' | xmllint --schema -

如果不是,您仍然可以使用非验证 xslt 处理器(xalan、saxon 等)对输入运行简单的 xslt 转换,然后才将其通过管道传输到 xmllint。

对于您上面列出的示例,xsl 应包含以下内容(xslt 处理器应支持 2.0):

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
    <xsl:for-each select="XML">
        <xsl:for-each select="Active">
            <xsl:value-of select=" replace(current(), 'True','true')"/>
        </xsl:for-each>
    </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

【讨论】:

  • 当心:我怀疑是否有任何“简单的sed 脚本”足够强大,可以正确地在 XML 文件上进行这样的替换——你的不是。