Немного странно, вот это, и я испытываю желание предположить, что это может быть ошибкой.Фон - у меня есть целая загрузка XML, которая выглядит следующим образом:
<foo id="1">
<bar id="0">
<baz id="0" blah="blah" etc="etc">
<buz id="0" />
</baz>
<buz id="0" blah="blah" etc="etc">
...
</buz>
</bar>
</foo>
<foo id="2">
<bar id="0">
<baz id="0" blah="blah" etc="etc">
<buz id="0" />
</baz>
<buz id="0" blah="blah" etc="etc">
...
</buz>
</bar>
</foo>
....
Я хочу преобразовать это так, чтобы для каждого элемента foo я заменял все нулевые идентификаторы внутри него наid foo.
Для этого - во-первых, я использую код Даниэля вместе с неявным преобразованием для предоставления 'Elem' метода mapAttributes:
class ElemWithUsefulAttributes(elem : Elem) extends Elem(elem.prefix, elem.label, elem.attributes, elem.scope, elem.child : _*) {
def mapAttributes(f : GenAttr => GenAttr) = this.copy(attributes = mapMetaData(elem.attributes)(f))
}
implicit def Elem2ElemWithUsefulAttributes(elem : Elem) = new ElemWithUsefulAttributes(elem)
Затем у меня есть метод replaceId:
def replaceId(attr : String, id : String)(in : GenAttr) = in match {
case g@GenAttr(_,key,Text(v),_) if (key.equals(attr)) => g.copy(value=Text(id))
case other => other
}
Наконец, я создаю пару RewriteRule
с и соответствующих RuleTransformer
с, чтобы справиться с этим:
class rw1(id : String) extends RewriteRule {
override def transform(n : Node) : Seq[Node] = n match {
case n2: Elem if (n2.label == "bar") => n2.mapAttributes(replaceId("id", id))
case n2: Elem if (n2.label == "baz") => n2.mapAttributes(replaceId("id", id))
case n2: Elem if (n2.label == "buz") => n2.mapAttributes(replaceId("id", id))
case other => other
}
}
class rt1(id : String) extends RuleTransformer(new rw1(id))
object rw2 extends RewriteRule {
override def transform(n : Node) : Seq[Node] = n match {
case n2@Elem(_, "foo", _, _, _*) => (new rw1(n2.attribute("id").get.toString))(n2)
case other => other
}
}
val rt2 = new RuleTransformer(rw2)
После вызова rt2(xml)
я получаю вывод, который выглядит следующим образом:
<foo id="1">
<bar id="1">
<baz id="0" blah="blah" etc="etc">
<buz id="1" />
</baz>
<buz id="0" blah="blah" etc="etc">
...
</buz>
</bar>
</foo>
<foo id="2">
<bar id="2">
<baz id="0" blah="blah" etc="etc">
<buz id="2" />
</baz>
<buz id="0" blah="blah" etc="etc">
...
</buz>
</bar>
</foo>
....
Другими словами, атрибуты не были изменены, когда имеется несколько атрибутов.Естественно, хочется предположить, что это проблема с кодом mapAttributes - однако, если я выгружу результаты преобразования в операторе 'match' в rw1
, я отчетливо вижу, что он показывает:
<baz id="2" blah="blah" etc="etc">
<buz id="2" />
</baz>
Далее, если я изменю один базис, скажем, чтобы удалить дополнительные атрибуты, тогда он будет работать правильно и будет отображен.Так что это кажется странным сочетанием множества атрибутов и преобразований.
Кто-нибудь может сделать из этого голову или хвост?