0

我正在解析一个 xml 文件,该文件可能有也可能没有一个名为的元素<Popular> ,该元素位于元素内<EName>

例子:

<Info>
<Enterprise>
<EName>
<Legal>Cool company</Legal>
</EName>
</Enterprise>
<Enterprise>
<EName>
<Legal>Cool company2</Legal>
<Popular>The company 2</Popular>
</EName>
</Enterprise>
</Info>

我像这样使用scala scales xml

val Info = NoNamespaceQName("Info")
val Enterprise = NoNamespaceQName("Enterprise")
val EName = NoNamespaceQName("EName")
val Legal = NoNamespaceQName("Legal")
val Popular = NoNamespaceQName("Popular")

val EnterprisePath = List(Info, Enterprise)

    val itr =  iterate(EnterprisePath, xml)
    for {
      enterprise <- itr
      enterpriseName <- enterprise \* EName \* Legal
      enterprisePopularName <- enterprise \* EName \* Popular 
    } {
      // Do fun stuff
      Logger.info("enterprise: "+enterpriseName + " "+enterprisePopularName)
}

发生的情况是,当 Popular 元素不存在时,for 语句没有执行,yield 语句也没有执行。

我想要的是首先检查元素,如果流行元素为空,请将 enterprisePopularName 设置为空字符串

就像是:

<- if((enterprise \* EName \* Popular)) enterprise \* EName \* Popular else ""      

但我无法弄清楚。我想这是因为我是一个 scala 新手。

4

2 回答 2

1

Impredicatives 答案会起作用,但Seq有一个很好的小方法,称为padTo,您可以使用它来确保序列内至少有 n 个值。它需要两个参数length: Intelem: B其中是您包含B的类型的子类型。Seq因此,在您的情况下,它将是:

for {
  enterprise <- itr
  enterpriseName <- enterprise \* EName \* Legal
  enterprisePopularName <- (enterprise \* EName \* Popular).padTo(1, reasonableDefaultValue)
}
于 2013-04-17T10:20:00.097 回答
0

警告:我不熟悉“秤”,所以这里的细节可能是错误的。特别是,您可能会发现:

  • \*不返回 a Seq- 它可能返回 a Iterable,在这种情况下只需替换SeqIterable,或一些自定义集合,在这种情况下,您需要弄清楚如何翻译以下方法。
  • 可能返回的序列是类型Seq[Node]或类似的,而不是Seq[String]- 您需要将默认值包装为节点,或者.map(_.toString)在应用默认值之前转换序列(使用 )。

我在这里假设\*返回某种序列(Scala's Seq)。我们想要的是一个接受 aSeq和一个默认值的方法,如果 aSeq为空,则生成默认值。请注意,这只是编写等效于Option'sorElsegetOrElse方法的情况。

这是我们可以做到的一种方法:

def orIfEmpty[A](xs : Seq[A], default : A) : Seq[A] = 
  if (xs.isEmpty) Seq(default) else xs

现在我们可以在理解中使用它:

enterprisePopularName <- orIfEmpty(enterprise \* EName \* Popular, "")
于 2013-04-17T10:32:41.753 回答