【问题标题】:XML. SAX . Attributes with default valueXML。萨克斯。具有默认值的属性
【发布时间】:2013-02-14 20:34:28
【问题描述】:

我使用 SAX 处理 XML 文件:

XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
reader.setFeature("http://xml.org/sax/features/validation", Boolean.TRUE);
reader.setFeature("http://apache.org/xml/features/validation/schema", Boolean.TRUE);

我加载一个语法 (XSD) 并将其设置给阅读器。

reader.setProperty("http://apache.org/xml/properties/internal/grammar-pool", grammarPool);

语法包含某些元素的某些可选属性的默认值。 那些具有默认值的属性会与此值一起从我的处理程序传递给 startElement(ContentHandler#startElement)) 方法,即使它们不存在于源 XML 中也是如此。 我能否以某种方式验证该属性是否存在于 XML 中?

【问题讨论】:

    标签: java xml-parsing sax


    【解决方案1】:

    这就是属性的默认值应该如何工作。如果您需要区分这两种情况(默认与显式指定但使用默认值),那么您必须从架构中删除默认值并改为在代码级别应用它。

    【讨论】:

      【解决方案2】:

      将功能标志http://xml.org/sax/features/use-attributes2 报告为true 的SAX2 解析器将为ContentHandler#startElement(String uri, String localName, String qName, Attributes atts)Attributes 参数提供Attributes2 接口的实例。此扩展接口提供了方法isSpecified(int index)isSpecified(String qName) 等方法,如果在文档中指定了属性,则测试true,如果通过DTD 或模式默认值,则测试false

      我发现的一个用例是在 EPUB 3.0.1 管道中从 XHTML 4.01 Transitional 转换为 (X)HTML5。我遇到的一个问题是过渡 DTD 具有 <br> 元素默认属性 clearnone;这个属性在 HTML5 中是 invalid 的。为了避免在 HTML5 中手动过滤所有无效属性,我通过过滤默认属性来重建 Attributes,如下所示:

      public static Attributes filterDefaults(Attributes attributes) {
          // Either test the feature flag, or do an instance test
          Attributes2 attrs = (Attributes2) attributes;
          Attributes2Impl newAttrs = new Attributes2Impl();
          for (int i = 0; i < attrs.getLength(); i++) {
              if (attrs.isSpecified(i)) {
                  final String qName = attrs.getQName(i);
                  final String type = attrs.getType(i);
                  final String value = attrs.getValue(i);
                  newAttrs.addAttribute(null, null, qName, type, value);
              }
          }
          return newAttrs;
      }
      

      XMLReader 应设置为验证 DTD 或架构以及输入 XML,或多或少如下:

      /**
       * @see "https://xerces.apache.org/xerces2-j/features.html"
       */
      private XMLReader buildParser(SAXParserFactory parserFactory) throws SAXException {
          try {
              final SAXParser parser = parserFactory.newSAXParser();
              final XMLReader reader = parser.getXMLReader();
              if (!reader.getFeature("http://xml.org/sax/features/use-attributes2"))
                  throw new SAXException("SAX2 parser with Attributes2 required");
      
              // Set your callback instances here
              reader.setEntityResolver(/*...*/);
              reader.setErrorHandler(/*...*/);
              reader.setContentHandler(/*...*/);
              reader.setProperty("http://xml.org/sax/properties/lexical-handler", /*...*/);
      
              reader.setFeature("http://xml.org/sax/features/namespaces", true);
              reader.setFeature("http://xml.org/sax/features/validation", true);
              reader.setFeature("http://apache.org/xml/features/validation/schema", true);
      
              return reader;
          } catch (ParserConfigurationException e) {
              throw new SAXException("Can't build parser", e);
          }
      }
      

      【讨论】:

      • 开启/关闭的默认功能列表在哪里?我在看 SAXParserFactoryImpl 但看不到它
      • 我能找到的唯一这样的列表是在 Apache 的Xerces 2 site
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多