针对XSD验证XML并丰富验证结果

时间:2014-04-16 13:32:48

标签: java xml validation xsd

我正在构建一个java工具来验证xml文档并构建一个包含输入数据和验证结果的html报告。 我认为可能的方法是:

  1. 使用XSD验证XML
  2. 使用验证结果丰富XML
  3. 转换最终HTML报告中的丰富XML(这一点不是问题的对象)
  4. 首先,这是一种有效的方法吗?或者有更合适的方法可以在java中完成这些工作?

    如果这是一个可行的解决方案,我该如何实施第2步?

    例如,如果我从这个输入文档开始:

    <parent>
        <child id="a correct id" type="a correct type"/>
        <child id="an incorrect id" type="an incorrect type"/>
    </parent>
    

    如何生成这样的丰富输出文档:

    <parent>
    
        <child id="a correct id" type="a correct type">
            <results>
                <result>id is correct</result>
                <result>type is correct</result>
            </results>
        </child>
    
        <child id="an incorrect id" type="an incorrect type">
            <results>
                <result>id is NOT correct</result>
                <result>type is NOT correct</result>
            </results>
        </child>
    
    </parent>
    

3 个答案:

答案 0 :(得分:2)

首先,有很多方法可以解决这个问题。还有其他工具,如schematron,它们提供用于描述验证结果的语言,以及将验证结果转换为漂亮HTML的能力。有许多实际进行模式验证的java包,因此您尝试完成的大多数应该是“粘合代码”。确保您不要尝试在Java代码中进行模式验证。

接下来,我不确定您在验证后想要转换原始XML文件的要求是什么。通常,您将验证结果集转储为单独的文件。原始XML的架构是否允许您添加的内容?

通常,如果要转换原始输入,可以通过编写获取验证结果文件和原始源文件的XSLT程序来解决此问题,然后使用这些验证结果转换原始文件。但我不建议这样做,因为我认为你的情况可能需要一个不会改变原始文件的不同设计,除非你有更多的要求,你想深入了解。

另一种选择是简单的DOM操作。验证后,您可以load the DOM for the input document对其进行操作,然后将其写回相同的原始文件。

但严重的是 - 在采用第2步的任何方法之前,请确保您的要求确实需要它。

答案 1 :(得分:1)

一种值得探索的方法:Xerces-J提供对模式验证后信息集(PSVI)的访问,实际上可以将其序列化为XML。至少对于小文档,您可能会发现PSVI的XML表示形式足以满足您的需要。

Xerces-J(和xsv)提供的PSVI表示不应该是输入的注释副本。但它可以转换为使用普通XML处理显示的形式。

答案 2 :(得分:0)

在我对XSD和XSLT有了更深入的了解和经验之后,我又回到了这个问题,最终建立了我的项目知识。

我原来的问题有一些误导性的观点。

我的目标是使用唯一目标处理XML,以生成相应的HTML报告,其中包含可读形式的XML数据以及针对一组业务规则的“验证”结果。

我错误的假设是我必须要针对XSD验证XML,但这给我带来了一些重大挑战:

  • XSD 1.0并不完全符合我的业务规则。所以我不得不切换到XSD 1.1
  • 然后我必须在java(Xerces2J)
  • 中设置一个符合XSD 1.1的验证器
  • 最后我开始考虑如何基于这些前提构建一个细粒度的验证器。

当时我意识到这个过程有点过分:我真正需要的只是从XML到HTML的转换:细粒度的验证可以在转换过程中完成,所有这些都与XSLT。

以最通用的形式回答我自己的问题: 我仍然会使用XSD进行非常基本的初步验证,然后使用XSLT检查更复杂的验证规则并丰富XML。

这是将我自己的问题的源xml转换为结果(仍然是XML)的XSLT。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="parent">

    <xsl:for-each select="child">
        <xsl:call-template name="processChildren"/>
    </xsl:for-each>

</xsl:template>

<!-- this template processes the children nodes, applying a sample test clause  -->
<xsl:template name="processChildren">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />

    <results>
    <xsl:choose>
        <xsl:when test="contains(@id,'incorrect')">
            <result>id is NOT correct</result>
        </xsl:when>
        <xsl:otherwise>
            <result>id is correct</result>
        </xsl:otherwise>
    </xsl:choose>

    <xsl:choose>
        <xsl:when test="contains(@type,'incorrect')">
            <result>type is NOT correct</result>
        </xsl:when>
        <xsl:otherwise>
            <result>type is correct</result>
        </xsl:otherwise>
    </xsl:choose>
    </results>

     </xsl:copy>
</xsl:template>

<!-- this template copy the contents of the node unaltered -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
    </xsl:template>

</xsl:stylesheet>