我一直在使用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'的内容无效。元素'断言'无效,错位或过于频繁发生。
任何线索或建议都会对我有帮助。
感谢。
............................................... .................................
很抱歉没有明确要求。让我再试一次。
解析后,我会将解析后的结构{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);
}
}
}
}
您对原始类型XML进行解析的建议似乎不适合我现有的XSOM解析器。即我正在寻找解析器API来获取标签的值,因此该解决方案对任何XSD都是通用的。
有关此方法的任何建议都有助于解决问题。
答案 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");
}