当前位置: 首页 > 面试题库 >

如何通过验证器获取有关无效DOM元素的更多信息?

王旺
2023-03-14
问题内容

我正在使用javax.xml.validation.Validator针对XSD架构的类来验证内存中的DOM对象。我得到一个SAXParseException验证过程中引发幸福每当有我填充从我的DOM一些信息数据损坏。

错误示例:

org.xml.SAXParseException:cvc-datatype-valid.1.2.1:’???“ ?? [????? G?> ???
p〜tn ??〜0?1]’是无效的评估为“ hexBinary”。

我希望有一种方法可以在内存中的DOM中找到此错误的位置,并打印出有问题的元素及其父元素。我当前的代码是:

public void writeDocumentToFile(Document document) throws XMLWriteException {
  try {
    // Validate the document against the schema
    Validator validator = getSchema(xmlSchema).newValidator();
    validator.validate(new DOMSource(document));

    // Serialisation logic here.

  } catch(SAXException e) {
    throw new XMLWriteException(e); // This is being thrown
  } // Some other exceptions caught here.
}

private Schema getSchema(URL schema) throws SAXException {
  SchemaFactory schemaFactory = 
    SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

  // Some logic here to specify a ResourceResolver

  return schemaFactory.newSchema(schema);
}

我已经研究了该Validator#setErrorHandler(ErrorHandler handler)方法,但是该ErrorHandler界面仅使我接触到了a
SAXParseException,该接触只暴露了错误的行号和列号。因为我使用的是内存中的DOM,所以行号和列号均返回-1。

有一个更好的方法吗?如果库为我提供了我想要的功能,我真的不需要在将字符串添加到DOM之前手动验证它们。

我正在使用JDK 6更新26和JDK 6更新7,具体取决于此代码的运行位置。

编辑:添加此代码-

validator.setErrorHandler(new ErrorHandler() {
  @Override
  public void warning(SAXParseException exception) throws SAXException {
    printException(exception);
    throw exception;
  }

  @Override
  public void error(SAXParseException exception) throws SAXException {
    printException(exception);
    throw exception;
  }

  @Override
  public void fatalError(SAXParseException exception) throws SAXException {
    printException(exception);
    throw exception;
  }

  private void printException(SAXParseException exception) {
    System.out.println("exception.getPublicId() = " + exception.getPublicId());
    System.out.println("exception.getSystemId() = " + exception.getSystemId());
    System.out.println("exception.getColumnNumber() = " + exception.getColumnNumber());
    System.out.println("exception.getLineNumber() = " + exception.getLineNumber());
  }
});

我得到的输出:

exception.getPublicId() = null
exception.getSystemId() = null
exception.getColumnNumber() = -1
exception.getLineNumber() = -1

问题答案:

如果使用Xerces(默认为Sun JDK),则可以通过http://apache.org/xml/properties/dom/current-
element-node
属性获取未通过验证的元素:

...
catch (SAXParseException e)
{
    Element curElement = (Element)validator.getProperty("http://apache.org/xml/properties/dom/current-element-node");

    System.out.println("Validation error: " + e.getMessage());
    System.out.println("Element: " + curElement);
}

例:

String xml = "<root xmlns=\"http://www.myschema.org\">\n" +
             "<text>This is text</text>\n" +
             "<number>32</number>\n" +
             "<number>abc</number>\n" +
             "</root>";

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
Schema schema = getSchema(getClass().getResource("myschema.xsd"));

Validator validator = schema.newValidator();
try
{
    validator.validate(new DOMSource(doc));
}
catch (SAXParseException e)
{
    Element curElement = (Element)validator.getProperty("http://apache.org/xml/properties/dom/current-element-node");

    System.out.println("Validation error: " + e.getMessage());
    System.out.println(curElement.getLocalName() + ": " + curElement.getTextContent());

    //Use curElement.getParentNode() or whatever you need here
}


 类似资料:
  • 问题内容: 我当前正在使用XSD验证xml。这部分工作正常,我的问题是我想获取无效的标记/值的元素。 我有一个不切实际的想法,就是在消息中查找“ type”或“ end- tag”一词,并在其后获取值,但是我知道这不是一个好习惯!我发现这很令人沮丧,因为我看到了无效但无法抓住的标签! 这是我想要的元素的一些示例 问题答案: 下面是一种使用来实现用例的方法: MyErrorHandler 我建议您实

  • 问题内容: 我正在使用PHPDOM,并且试图在DOM节点中获取具有给定类名的元素。获得该子元素的最佳方法是什么? 更新: 我最终使用了PHP,它更容易使用。 问题答案: 更新:CSS选择器的Xpath版本 因此,在下面我回应hakre的评论之后,我感到好奇,并调查了后面的代码。看起来上面的选择器已编译为以下xpath(未经测试): 所以PHP将是: 基本上,我们在这里所做的就是规范化属性,以便即使

  • 问题内容: 我知道我可以按元素获取范围: 我该如何反向:使用scope来查找DOM元素,例如? 我想这样做是为了调试。我的作用域树显示了一些内容,我想确定它的来源。 问题答案: 尽管不是很性感,但每个dom节点都有一个ng-scope类,因此您可以通过技术进行如下操作:

  • 问题内容: 如果我知道文本标签包含什么,如何在html页面中获取标签。例如: 问题答案: 您将不得不手动遍历。

  • 问题内容: 我想知道是否有一种功能或某种与之等效的方法。 问题答案: 您的函数名称中缺少。返回元素的集合,这些元素需要迭代: IE8及以下版本不支持,因此您必须找到一个polyfill或使用(IE8)。

  • 问题内容: 使用JavaScript,我们可以使用以下语法通过id获取元素: 我尝试以下按类获取元素: 但这导致了错误: 如何按类获取元素? 问题答案: DOM函数的名称实际上不是,仅仅是因为页面上的多个元素可以具有同一类,因此:。 此方法的返回值将是NodeList实例,或者是(FF的超集,例如返回的实例)。无论如何:返回值是一个类似于数组的对象: 如果由于某种原因需要返回对象作为数组,则由于其