我收到一个大型XML文件,并且XML文件通常不会验证到架构文件。 我没有删除整个xml文件,而是删除“无效”内容并保存XML文件的其余部分。
我正在使用xmllint通过此命令验证xml:
xmllint -schema testSchedule.xsd testXML.xml
XSD文件(在此示例中名为testSchedule.xsd):
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.testing.dk" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="MasterData">
<xs:complexType>
<xs:sequence>
<xs:element name="Items">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:integer" name="Id" minOccurs="1"/>
<xs:element type="xs:integer" name="Width" minOccurs="1"/>
<xs:element type="xs:integer" name="Height" minOccurs="0"/>
<xs:element type="xs:string" name="Remark"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XML文件(在本例中名为testXML.xml):
<?xml version="1.0" encoding="ISO-8859-1" ?>
<MasterData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.testing.dk">
<Items>
<Item>
<Id>1</Id>
<Width>10</Width>
<Height>100</Height>
<Remark>This is OK</Remark>
</Item>
<Item>
<Id>2</Id>
<Width>20</Width>
<Height>200</Height>
<Remark>This is OK - But is missing Height a non mandatory field</Remark>
</Item>
<Item>
<Id>3</Id>
<Height>300</Height>
<Remark>This is NOT OK - Missing the mandatory Width</Remark>
</Item>
<Item>
<Id>4</Id>
<Width>TheIsAString</Width>
<Height>200</Height>
<Remark>This is NOT OK - Width is not an integer but a string</Remark>
</Item>
<Item>
<Id>5</Id>
<Width>50</Width>
<Height>500</Height>
<Remark>This is OK and the last</Remark>
</Item>
</Items>
</MasterData>
然后我得到了xmllint命令的结果:
testXML.xml:18: element Height: Schemas validity error : Element '{http://www.testing.dk}Height': This element is not expected. Expected is ( {http://www.testing.dk}Width ).
testXML.xml:23: element Width: Schemas validity error : Element '{http://www.testing.dk}Width': 'TheIsAString' is not a valid value of the atomic type 'xs:integer'.
testXML.xml fails to validate
这一切都是正确的 - XML文件中有两个错误。
现在我想使用某种工具来删除第3项和第4项,所以我最终得到了这个结果:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<MasterData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.testing.dk">
<Items>
<Item>
<Id>1</Id>
<Width>10</Width>
<Height>100</Height>
<Remark>This is OK</Remark>
</Item>
<Item>
<Id>2</Id>
<Width>20</Width>
<Height>200</Height>
<Remark>This is OK - But is missing Height a non mandatory field</Remark>
</Item>
<Item>
<Id>5</Id>
<Width>50</Width>
<Height>500</Height>
<Remark>This is OK and the last</Remark>
</Item>
</Items>
</MasterData>
这里有人有一个可以做到这一点的工具吗? 我目前正在使用bash脚本和xmllint。 我真的希望有人能提供帮助。
答案 0 :(得分:0)
您可以使用此命令行工具(例如xsltproc
(libxslt
)或Saxon,在任何支持XSLT 1.0(大多数语言)的环境中运行的XSLT样式表实现此目的。浏览器或在线工具。这是一个例子。
如果您使用以下样式表将原始XML文件作为输入提供给XSLT转换器,它将生成您在第二个XML中显示的结果:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:t="http://www.testing.dk">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="t:Item[t:Id and not(number(t:Id))]"/>
<xsl:template match="t:Item[t:Width and not(number(t:Width))]"/>
<xsl:template match="t:Item[t:Height and not(number(t:Height))]"/>
<xsl:template match="t:Item[not(t:Width)]"/>
<xsl:template match="t:Item[not(t:Id)]"/>
<xsl:template match="t:Item[not(t:Remark)]"/>
</xsl:stylesheet>
第一个<xsl:template>
块只是将源树中的所有节点复制到结果树中。它的优先级低于按名称匹配节点的特定模板。
由于匹配是在XPath中完成的,需要使用名称空间限定的选择器,因此您的默认命名空间在<xsl:stylesheet>
开始标记中声明,并映射到用于限定标记名称的前缀。
每个模板使用XPath表达式来测试Item
中是否存在特定子元素,或者该子元素是否存在,如果它是一个数字(根据XSD)。
我正在使用XSLT 1.0,它受到更广泛的支持,应该更容易在您的环境中找到。但是,如果您可以使用XSLT 2.0处理器,则可以使用XSLT 2.0等XSLT 2.0功能,而不是将您的值与数字类型进行比较,您可以将它们与xsd:integer
等特定类型进行比较。
您可以通过此 XSLT Fiddle 中的样式表验证对示例XML执行的转换。
如果您创建包含上述代码的XML文档并将其放在名为stylesheet.xsl
的文件中,则可以使用xsltproc
(可能存在于您的环境中)使用以下命令运行转换:
xsltproc stylesheet.xsl testXML.xml > fixedXML.xml