如何解析XSD1.1功能,精确地<xs:assert>标签?

时间:2015-10-15 13:14:18

标签: java xml parsing xsd xsd-1.1

我一直在使用XSOM解析器(xsom-20140925.jar)来解析XSD 1.0并能够实现解析所有xs:元素和限制(如pattern,minOccurs等)。

最近我们的XSD1.0已升级到版本XSD1.1,其中包含新的断言标记。 我的XSOM解析器无法识别此断言标记并引发以下异常。

无法解析输入流:org.xml.sax.SAXParseException:意外的<xsd:assert>出现在行中。 显示java.lang.NullPointerException

基本上我需要将XSD中的所有限制自动化为JavaScript函数,以便验证客户端UI。

我已经完成谷歌搜索,并了解Xerces-j只能针对XSD1.1验证XML。

但我的要求是解析断言值并转换为JavaScript函数。

考虑以下断言示例:这里我需要解析双引号“”之间的值,并根据条件到达JavaScript函数。

xsd:assert test="(exists(companyName) and companyTier='TierOne')"

有没有办法达到上述要求? 任何帮助或建议都会对我有所帮助。

............................................... ...............................

感谢您的回答。 通过关闭sax validaiton将允许我解析assert标记值。 但我的要求是将那些XSD1.1特征的断言值(如下所示)转换为Java正则表达式或任何可以评估的表达式 而且我应该有正确的链接,即这个断言标签属于哪个元素。

我理解xercesImpl-xsd11-2.12-beta有Xpath2.0处理器可以使用。 但我无法使用断言标记将XSD解析为XSModel。

使用XSD文件:

<?xml version="1.1" encoding="UTF-8"?>
<schema targetNamespace="http://www.example.org/Example" elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.example.org/Example">
    <element name="Node" type="tns:NodeType"></element>
    <complexType name="NodeType">
        <sequence>
            <element name="Node" type="tns:NodeType"
                maxOccurs="unbounded" minOccurs="0">
            </element>
        </sequence>
        <attribute name="partnumber">
            <simpleType>
                <restriction base="string">
                    <pattern value="[A-Z0-9_\-]+"></pattern>
                </restriction>
            </simpleType>
        </attribute>
        <assert test="starts-with(@partnumber,../@partnumber)"/>
    </complexType>
</schema>

要解析的Java代码:

System.setProperty(DOMImplementationRegistry.PROPERTY,“org.apache.xerces.dom.DOMXSImplementationSourceImpl”);

    DOMImplementationRegistry registry;
    XSNamedMap xsMap;
    try {
        registry = DOMImplementationRegistry.newInstance();

        XSImplementationImpl impl = (XSImplementationImpl) registry.getDOMImplementation("XS-Loader");
        XSLoader schemaLoader = impl.createXSLoader(null);
        XSModel model = schemaLoader.loadURI("testxsdassert.xsd");
        }

执行以下错误时,控制台中显示: [错误] testxsdassert.xsd:17:65:s4s-elt-invalid-content.1:'NodeType'的内容无效。元素'断言'无效,错位或过于频繁发生。

任何线索或建议都会对我有帮助。

感谢。

............................................... .................................

很抱歉没有明确要求。让我再试一次。

  1. 现有的XSOM解析器(参见下面的代码)将解析任何XSD,并针对XSD中存在的任何元素检索所有限制,如MINLENGTH,MAXLENGTH,PATTERN,ENUMERATION。 此解析器的目的是解析这些值并存储其元素名称。 对于以下示例(parser.xsd),此结构是派生的 - &gt; {allowedMonths,[“JAN”,“FEB”]}
  2. 解析后,我会将解析后的结构{allowedMonths,[“JAN”,“FEB”]}转换为JavaScript函数,其中在UI验证中调用此函数以检查用户输入的值是否动态地符合XSD。 / p>

    到目前为止工作正常。这个解决方案是自动化的,这样在XSD中的任何新增内容中,这个解析器都应该关注JS代码的生成。

    **Parser.xsd**
        <xsd: simpleType name="allowedMonths">
                <xsd:restriction base="xsd:string">
                <xsd:enumeration value="JAN"/>
                <xsd:enumeration value="FEB"/>
                </xsd:restriction>
                </xsd:simpleType>
     **Parser.java**
                XSOMParser parser;
                parser.parse(xml);
                XSSchemaSet schemaSet = null;
                    try {
                        schemaSet = parser.getResult();
                    } catch (SAXException ex) {
                        System.out.println("Could not parse: " + ex);
                    }
                    Iterator <XSElementDecl> itre = schemaSet.iterateElementDecls();
                     while(itre.hasNext()) {
                        XSElementDecl xse = (XSElementDecl) itre.next();
                        hmReturned.put(xse.getName(), hm);
                        XSComplexType xscomp = xse.getType().asComplexType();
                        if (xscomp != null) {
                            XSContentType xscont = xscomp.getContentType();
                            XSParticle particle = xscont.asParticle();
                            getElementsRecursively(hm,  particle);
                        }
                    } 
    
                    private void getElementsRecursively(HashMap<String, Object> hm, XSParticle xsp) {
    
                     if(xsp != null){
                         XSTerm term = xsp.getTerm();
                         if(term.isElementDecl()) {
                             XSComplexType xscmp =  (term.asElementDecl()).getType().asComplexType();
                             //---
                             if (xscmp == null){
                                 MappingXSDJSElement mapElementObj = new MappingXSDJSElement();
                                 //public List<String> enumeration = new ArrayList<String>();
                                 if(xsp.getTerm().asElementDecl().getType().asSimpleType() != null)
                                 {
                                     if(xsp.getTerm().asElementDecl().getType().asSimpleType().isRestriction())
                                     {
                                         XSRestrictionSimpleType restriction=xsp.getTerm().asElementDecl().getType().asSimpleType().asRestriction();
                                         if(restriction != null){
                                                List<String> enumeration = new ArrayList<String>();
                                                Iterator<? extends XSFacet> i = restriction.getDeclaredFacets().iterator();
                                                while(i.hasNext()){
                                                    XSFacet facet = i.next();
    
                                                    if(facet.getName().equals(XSFacet.FACET_MAXLENGTH)){
                                                        mapElementObj.setMaxLength(facet.getValue().value);
    
                                                    }
                                                    if(facet.getName().equals(XSFacet.FACET_MINLENGTH)){
                                                        mapElementObj.setMinLength(facet.getValue().value);
    
                                                    }
                                                    if(facet.getName().equals(XSFacet.FACET_PATTERN)){
                                                        mapElementObj.setPattern(facet.getValue().value);
    
                                                    }
                                                    if(facet.getName().equals(XSFacet.FACET_ENUMERATION)){
                                                        enumeration.add(facet.getValue().value);
                                                        mapElementObj.setEnumeration(enumeration);
                                                       // System.out.println(enumeration.toString());
                                                    }
    
                                                }
                                            }    
                                     }
                                 }
                                 if(xsp.getMinOccurs().intValue() == 0)
                                 {
                                    // hm.put(term.asElementDecl().getName(), "|");
                                     mapElementObj.setMinOccurs("0");
                                 }
                                 else if(xsp.getMinOccurs().intValue() == 1)
                                 {
                                    // hm.put(term.asElementDecl().getName(), "=");
                                     mapElementObj.setMinOccurs("1");
                                 }
    
                                 hm.put(term.asElementDecl().getName(), mapElementObj);
    
                             } else{
                                 XSContentType xscont = xscmp.getContentType();
                                 XSParticle particle = xscont.asParticle();
                                 HashMap<String, Object> newHm = new HashMap<String, Object>();
                                 getElementsRecursively(newHm, particle);
                                 hm.put(term.asElementDecl().getName(), newHm);
                             }
                             //---
                         } else if(term.isModelGroup()){
                             XSModelGroup model = term.asModelGroup();
                             XSParticle[] parr = model.getChildren();
                             for(XSParticle partemp : parr ){
                               getElementsRecursively(hm, partemp);
                             }
                         }
                     }
                }
    
    1. 要求:现在XSD已得到增强,包括进行跨领域验证。所以最终我必须增强我的解析器来捕获每个元素的这些断言并到达JavaScript函数 对于XSD的每个元素。 所以我需要找到一种解析任何简单和复杂类型元素中存在的断言值的方法。
    2. 您对原始类型XML进行解析的建议似乎不适合我现有的XSOM解析器。即我正在寻找解析器API来获取标签的值,因此该解决方案对任何XSD都是通用的。

      有关此方法的任何建议都有助于解决问题。

1 个答案:

答案 0 :(得分:0)

在关闭验证的情况下解析XSD,以便将其作为原始XML文件读取,然后无论是1.0还是1.1 XSD都无关紧要。

Set http://xml.org/sax/features/validation功能为false:

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

try {
    dbf.setFeature("http://xml.org/sax/features/validation", false);
} catch (ParserConfigurationException e) {
    System.err.println("could not set parser feature");
}