如何迭代可以具有可选属性的 XML 元素?

发布于 2024-12-26 06:43:23 字数 3667 浏览 1 评论 0原文

我尝试迭代 XML 文件以获取特定类型 的所有元素。该类型还可以具有可选的属性。

XML 示例:

<Lesson>
  <Description>Description</Description>
  <Card learnedTimestamp="1234567", isRepeatedByTyping="true", batch="5">
      <FrontSide>Foo1</FrontSide>
      <ReverseSide>Bar1</ReverseSide>
      <InformationLine>Info1</InformationLine>
  </Card>
  <Card>
      <FrontSide>Foo2</FrontSide>
      <ReverseSide>Bar2</ReverseSide>
      <InformationLine>Info2</InformationLine>
  </Card>
</Lesson>

Scala 代码:

    class XMLParser(fqFileName: String) {
      val pauDoc: Elem = XML.loadFile(fqFileName)
      def printXMLFile() = {
        var cardCount = 0
        val lesson = (pauDoc \\ "Lesson")    
        for(val card <- lesson \\ "Card"){      
          cardCount = cardCount + 1
          println("Card No " + cardCount)
          val frontSide = (card \\ "FrontSide").text
          println("FrontSide Value: " + frontSide)      
          val reverseSide = (card \\ "ReverseSide").text
          println("ReverseSide Value.text: " + reverseSide)      
          val infoLine = (card \\ "InformationLine").text
          println("InformationLine Value: " + infoLine)      
        }    
      }
    }

但此代码仅在 元素没有任何属性时才有效。有谁知道我如何处理属性,特别是如果它们是可选的?

PS:这是我得到的例外。

    Exception in thread "main" org.xml.sax.SAXParseException: Element type "Card" must be followed by either attribute specifications, ">" or "/>".
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.seekCloseOfStartTag(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
        at javax.xml.parsers.SAXParser.parse(Unknown Source)
        at scala.xml.factory.XMLLoader$class.loadXML(XMLLoader.scala:40)
        at scala.xml.XML$.loadXML(XML.scala:40)
        at scala.xml.factory.XMLLoader$class.loadFile(XMLLoader.scala:49)
        at scala.xml.XML$.loadFile(XML.scala:40)
        at de.htwg_konstanz.ecardman.common.XMLParser.<init>(XMLParser.scala:7)
        at de.htwg_konstanz.ecardman.common.XMLParserMain$.main(XMLParserMain.scala:23)
        at de.htwg_konstanz.ecardman.common.XMLParserMain.main(XMLParserMain.scala)

I try to iterate over a XML file to fetch all elements of a specific type <Card>. This type can also have attributes which are optional.

XML Sample:

<Lesson>
  <Description>Description</Description>
  <Card learnedTimestamp="1234567", isRepeatedByTyping="true", batch="5">
      <FrontSide>Foo1</FrontSide>
      <ReverseSide>Bar1</ReverseSide>
      <InformationLine>Info1</InformationLine>
  </Card>
  <Card>
      <FrontSide>Foo2</FrontSide>
      <ReverseSide>Bar2</ReverseSide>
      <InformationLine>Info2</InformationLine>
  </Card>
</Lesson>

Scala code:

    class XMLParser(fqFileName: String) {
      val pauDoc: Elem = XML.loadFile(fqFileName)
      def printXMLFile() = {
        var cardCount = 0
        val lesson = (pauDoc \\ "Lesson")    
        for(val card <- lesson \\ "Card"){      
          cardCount = cardCount + 1
          println("Card No " + cardCount)
          val frontSide = (card \\ "FrontSide").text
          println("FrontSide Value: " + frontSide)      
          val reverseSide = (card \\ "ReverseSide").text
          println("ReverseSide Value.text: " + reverseSide)      
          val infoLine = (card \\ "InformationLine").text
          println("InformationLine Value: " + infoLine)      
        }    
      }
    }

But this code only works if the <Card> element does not have any attribute. Does anybody know how I deal with attributes, especially if they are optional?

P.S.: This is the exception i get.

    Exception in thread "main" org.xml.sax.SAXParseException: Element type "Card" must be followed by either attribute specifications, ">" or "/>".
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.seekCloseOfStartTag(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
        at javax.xml.parsers.SAXParser.parse(Unknown Source)
        at scala.xml.factory.XMLLoader$class.loadXML(XMLLoader.scala:40)
        at scala.xml.XML$.loadXML(XML.scala:40)
        at scala.xml.factory.XMLLoader$class.loadFile(XMLLoader.scala:49)
        at scala.xml.XML$.loadFile(XML.scala:40)
        at de.htwg_konstanz.ecardman.common.XMLParser.<init>(XMLParser.scala:7)
        at de.htwg_konstanz.ecardman.common.XMLParserMain$.main(XMLParserMain.scala:23)
        at de.htwg_konstanz.ecardman.common.XMLParserMain.main(XMLParserMain.scala)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情深已缘浅 2025-01-02 06:43:23

这在 2.9.1 上适用于我:

val raw = """<Lesson>
  <Description>Description</Description>
  <Card learnedTimestamp="1234567" isRepeatedByTyping="true" batch="5">
      <FrontSide>Foo1</FrontSide>
      <ReverseSide>Bar1</ReverseSide>
      <InformationLine>Info1</InformationLine>
  </Card>
  <Card>
      <FrontSide>Foo2</FrontSide>
      <ReverseSide>Bar2</ReverseSide>
      <InformationLine>Info2</InformationLine>
  </Card>
</Lesson>"""

class XMLParser(fqFileName: String) {
  import xml._
  val pauDoc: Elem = XML.loadString(fqFileName)
  def printXMLFile() = {
    var cardCount = 0
    val lesson = (pauDoc \\ "Lesson")    
    for(card <- lesson \\ "Card"){      
      cardCount = cardCount + 1
      println("Card No " + cardCount)
      val frontSide = (card \\ "FrontSide").text
      println("FrontSide Value: " + frontSide)      
      val reverseSide = (card \\ "ReverseSide").text
      println("ReverseSide Value.text: " + reverseSide)      
      val infoLine = (card \\ "InformationLine").text
      println("InformationLine Value: " + infoLine)      
    }    
  }
}

new XMLParser(raw).printXMLFile()

这打印:

Card No 1
FrontSide Value: Foo1
ReverseSide Value.text: Bar1
InformationLine Value: Info1
Card No 2
FrontSide Value: Foo2
ReverseSide Value.text: Bar2
InformationLine Value: Info2

这不是你所期望的吗?我只是使用了 loadString 而不是 loadFile,但这只是为了测试。

This works for me on 2.9.1:

val raw = """<Lesson>
  <Description>Description</Description>
  <Card learnedTimestamp="1234567" isRepeatedByTyping="true" batch="5">
      <FrontSide>Foo1</FrontSide>
      <ReverseSide>Bar1</ReverseSide>
      <InformationLine>Info1</InformationLine>
  </Card>
  <Card>
      <FrontSide>Foo2</FrontSide>
      <ReverseSide>Bar2</ReverseSide>
      <InformationLine>Info2</InformationLine>
  </Card>
</Lesson>"""

class XMLParser(fqFileName: String) {
  import xml._
  val pauDoc: Elem = XML.loadString(fqFileName)
  def printXMLFile() = {
    var cardCount = 0
    val lesson = (pauDoc \\ "Lesson")    
    for(card <- lesson \\ "Card"){      
      cardCount = cardCount + 1
      println("Card No " + cardCount)
      val frontSide = (card \\ "FrontSide").text
      println("FrontSide Value: " + frontSide)      
      val reverseSide = (card \\ "ReverseSide").text
      println("ReverseSide Value.text: " + reverseSide)      
      val infoLine = (card \\ "InformationLine").text
      println("InformationLine Value: " + infoLine)      
    }    
  }
}

new XMLParser(raw).printXMLFile()

This prints:

Card No 1
FrontSide Value: Foo1
ReverseSide Value.text: Bar1
InformationLine Value: Info1
Card No 2
FrontSide Value: Foo2
ReverseSide Value.text: Bar2
InformationLine Value: Info2

Isn't it what you expect? I just used loadString instead of loadFile, but that's just for testing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文