【问题标题】:ready made parser in javajava中现成的解析器
【发布时间】:2010-11-23 15:21:23
【问题描述】:

我有一些用户定义的标签。例如这里的数据,jssj。我有一个文件(不是xml),其中包含一些嵌入在标签中的数据。我需要一个解析器来识别我的标签并以正确的格式提取数据。 例如

<newpage> thix text </newpage>
<tagD>
 <tagA> kk</tagA>
</tagD>

标签也可以有一些类似于 html 标签的属性。例如

<mytag height="f" width ="d" > bla bla bla </mytag>
<mytag attribute="val"> bla bla bla</mytag>

【问题讨论】:

  • 如果你添加一些根元素,这个就是 XML。
  • 停止让自己变得异常困难,并添加一个根元素以使其成为有效的 XML。有大量用于 Java 的 XML 解析工具和库 - 没有必要重新发明轮子。
  • 而且每个 mytag 的属性并不总是相同的事实并不重要,只要您不绑定到 XML 模式/DTD(当您这样做时,您需要包括所有可能的属性作为可选属性)

标签: java xml parsing


【解决方案1】:

这些是 XML 标记吗?如果是这样,请查看已经可用的众多 Java XML 库之一。如果它们是某种自定义标记格式,那么您只需要自己编写即可。

【讨论】:

    【解决方案2】:

    对于 xml 标签 - 使用 DOM 解析器或 SAX 解析器。

    【讨论】:

    • 它们不是 xml 标签。文本不是 xml 文件
    【解决方案3】:

    您可以查看像 antlr 这样的解析器生成器。

    除非您的标签语法可以用(简单)常规语法表示(在这种情况下,您可以尝试使用正则表达式扫描文件),否则您将需要一个合适的解析器。其实一点也不难做——只是第一次尝起来像咬子弹……

    【讨论】:

      【解决方案4】:

      您的示例是经过此修改的 XML:

      <root>
        <newpage> thix text </newpage>
        <tagD>
          <tagA> kk</tagA>
        </tagD>
      </root>
      

      您可以使用任何您想要解析的 XML 解析器。

      编辑:

      属性是 XML 的正常部分。

      <root>
        <newpage> thix text </newpage>
        <tagD>
          <tagA> kk</tagA>
        </tagD>
        <mytag height="f" width ="d" > bla bla bla </mytag>
        <mytag attribute="val"> bla bla bla</mytag>
      </root>
      

      每个 XML 解析器都可以处理它们。

      编辑:

      如果你能够使用 Python,你可以这样做:

      import lxml.etree
      
      doc = lxml.etree.parse("foo.xml")
      print doc.xpath("//mytag[1]/@width")
      # => ['d']
      

      这就是我所说的简单。

      【讨论】:

      • 如果标签有可选属性,我能做什么?我现在在主帖中给出了一个例子
      • 我有什么像 我的名字是 hhshs
      • 它仍然是 XML。元素根将包含合法的混合内容。
      【解决方案5】:

      您可以使用已包含在 Java 中的 JAXB。这很简单。 首先,您需要创建与 XML 代码的绑定。该绑定提供了 Java 对象和 XML 代码之间的映射。

      一个例子是:

      @XmlRootElement(name = "YourRootElement", namespace ="http://someurl.org")
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlType(name = "", propOrder = {
          "intValue",
          "stringArray",
          "stringValue"}
      )
      public class YourBindingClass {
          protected int intValue;
      
          @XmlElement(nillable = false)
          protected List<String> stringArray;
      
          @XmlElement(name = "stringValue", required = true)
          protected String stringValue;
      
          public int getIntValue() {
              return intValue;
          }
      
          public void setIntValue(int value) {
              this.intValue = value;
          }
      
          public List<String> getStringArray() {
              if (stringArray == null) {
                  stringArray = new ArrayList<String>();
              }
              return this.stringArray;
          }
      
          public String getStringValue() {
              return stringValue;
          }
      
          public void setStringValue(String value) {
              this.stringValue = value;
          }
      }
      

      然后,要将您的 Java 对象编码为 XML,您可以使用:

      YourBindingClass yourBindingClass = ...;
      JAXBContext jaxbContext = JAXBContext.newInstance(YourBindingClass.class);
      Marshaller marshaller = jaxbContext.createMarshaller();
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);
      
      /** If you need to specify a schema */
      SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
      Schema schema = sf.newSchema(new URL("http:\\www.someurl.org"));      
      marshaller.setSchema(schema);
      marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, true);
      
      ByteArrayOutputStream stream = new ByteArrayOutputStream();
      marshaller.marshal(yourBindingClass, stream);
      System.out.println(stream);
      

      将您的 XML 解析回对象:

      InputStream resourceAsStream = ... // Your XML, File, etc. 
      JAXBContext jaxbContext = JAXBContext.newInstance(YourBindingClass.class);
      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
      Object r = unmarshaller.unmarshal(resourceAsStream);
      if (r instanceof YourBindingClass) ...
      

      从 Java 对象开始的示例:

      YourBindingClass s = new YourBindingClass();
      s.setIntValue(1);
      s.setStringValue("a");
      s.getStringArray().add("b1");
      s.getStringArray().add("b2");
      
      // marshal ...
      

      结果:

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <ns2:YourRootElement xmlns:ns2="http://someurl.org">
          <intValue>1</intValue>
          <stringArray>b1</stringArray>
          <stringArray>b2</stringArray>
          <stringValue>a</stringValue>
      </ns2:YourRootElement>
      

      如果您不知道输入格式,那意味着您可能没有 XML 模式。如果您没有架构,您就没有一些它的好处,例如:

      • 更容易描述允许的文档内容
      • 更容易验证数据的正确性
      • 更容易定义数据方面(数据限制)
      • 更容易定义数据模式(数据格式)
      • 不同数据类型之间的数据转换更容易

      无论如何,前面的代码也适用于包含“未知”标签的 XML 代码。但是,您的 XML 代码仍然必须提供必填字段并遵循声明的模式。 所以下面的 XML 代码也是有效的。唯一的限制是:标签“stringValue”应该在那里。请注意,之前未声明“stringArrayQ”。

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <ns2:YourRootElement xmlns:ns2="http://someurl.org">
               <stringValue>a</stringValue>
               <stringArrayQ>b1</stringArrayQ>
      </ns2:YourRootElement>
      

      【讨论】:

      • 可能你是对的 :) 我太热情了。为长 XML 代码编写绑定应该很无聊。无论如何,至少在 DOM 解析器上,您会获得良好的性能。
      • 我事先不知道输入文件的格式。输入文件不是特定格式。我唯一事先知道的是它可以包含的标签。例如,tag1 可以嵌套在 tag2 或 tag3 或任何其他组合中。就像我们如何使用一些 html 标签一样。 html 例如

        数据

        data
      猜你喜欢
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多