2

如何根据给定的 xsd-schema 将无效的 XML 转换为有效的 XML?例如,我有下一个 xsd 架构:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="note">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="to" type="xs:string"/>
      <xs:element name="from" type="xs:string"/>
      <xs:element name="heading" type="xs:string"/>
      <xs:element name="body" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
</xs:schema>

和下一个无效的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<note xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../my_xsd.xsd">
  <to>reviver@mail.com</to>
  <from>sender@mail.com</from>
  <body>blablabla</body> <!-- IVALID LINE, IT IS NOT IN RIGHT PALCE -->
  <heading>head</heading>
</note>

我的问题是:JAXB、XSTREAM 或其他 XML 解析器是否有解决方案来根据给定模式将我的无效 XML 转换为有效 XML:

<?xml version="1.0" encoding="UTF-8"?>
<note xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../my_xsd.xsd">
  <to>reviver@mail.com</to>
  <from>sender@mail.com</from>
  <heading>head</heading>
  <body>blablabla</body>
</note>
4

2 回答 2

1

如果您需要对项目进行重新排序,您可能必须首先在没有 xsd 的情况下阅读它们,然后使用 xslt 根据 xsd 的喜好对它们进行排序。

于 2012-11-21T15:47:49.593 回答
0

假设:我假设输入是格式良好的 XML。

一般来说答案是否定的……没有算法能够将任意XML 输入文档转换为给定模式的有效且语义正确的实例。

但是,如果输入无效的方式仅限于一小部分问题,例如子元素<note>乱序,那么的,几乎任何 XML 解析和序列化库都可以帮助您解决问题。正如@KevinDTimm 所暗示的那样,您需要关闭这些工具中的模式验证,以便它们在修复之前不会拒绝输入。

我个人会使用 XSLT,因为我已经习惯了。您可以让它以它们出现的任何顺序读取子元素,并以正确的顺序将它们输出为 XML:

<xsl:template match="note">
  <xsl:copy>
    <xsl:apply-templates select="to" />
    <xsl:apply-templates select="from" />
    <xsl:apply-templates select="heading" />
    <xsl:apply-templates select="body" />
  </xsl:copy>
</xsl:template>

但是您列出的示例工具 - JAXB 和 XSTREAM - 不仅是 XML 解析器,而且是 XML对象解析器/序列化器。如果您需要在构建对象时纠正验证错误,那会使事情变得复杂。一个单独的更正然后反序列化的过程会更简单。

于 2012-11-21T15:50:44.717 回答