Scala RewriteRules 来设置命名空间 &架构位置? [英] Scala RewriteRules to set namespace & schemaLocation?

查看:38
本文介绍了Scala RewriteRules 来设置命名空间 &架构位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在生成一个 xml 文件,并希望创建一些转换 RewriteRules 将以下内容插入到根元素中:

I'm generating an xml file and want to create some transform RewriteRules that will insert the following into the root element:

<content
  xmlns:ns="http://example.com/ns"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://example.com/ns http://example.com/xml/xsd/xml-schema-articles-v1.0.xsd">

看起来从这个要点设置xmls:ns命名空间是创建一个 NamespaceBinding 并将其应用为 Elem 的范围的问题.但是,我还没有为此成功创建 RewriteRule,我仍在寻找如何添加架构实例 (xmlns:xsi) 和 schemaLocation.

It looks from this gist that setting the xmls:ns namespace is a matter of creating a NamespaceBinding and applying that as the Elem's scope. However, I haven't successfully created a RewriteRule for this yet, and I'm still searching for how to add the schema instance (xmlns:xsi) and the schemaLocation.

推荐答案

// start with a sample xml 'document'
val xml = <root attr="willIStayOrWillIGoAway"><container/></root>

// create a namespace binding using TopScope as the "parent" argument 
val ns = new NamespaceBinding("ns", "http://example.com/ns", TopScope)

// create a second namespace binding, and pass "ns" as the new parent argument
val xsi = new NamespaceBinding("xsi", "http://www.w3.org/2001/XMLSchema-instance", ns)

注意我们做了两个 NamespaceBindings,但是因为它们是链接"在一起的,所以我们只需要将最后一个传递给我们的 RuleTransformer 类.

Notice that we made two NamespaceBindings, but because they are "chained" together, we only need to pass the last one to our RuleTransformer class.

// the schemaLocation needs to be a PrefixedAttribute
val schemaLoc = new PrefixedAttribute("xsi", "schemaLocation", "http://example.com/ns http://example.com/xml/xsd/xml-schema-articles-v1.0.xsd", Null)

xmlns:nsxmlns:xsi 属性实际上是 NamespaceBindings - 我不知道为什么它们的处理方式不同.但是 xsi:schemaLocation 实际上是一个作用域属性,所以我们使用 PrefixedAttribute.

The xmlns:ns and xmlns:xsi attributes are actually NamespaceBindings - I have no idea why they're handled differently. But the xsi:schemaLocation is actually a scoped attribute so we use a PrefixedAttribute.

// in order to limit the insertion to the root node, you'll need it's label
val rootNodeLabel = "root"

// make a new RewriteRule object
val setSchemaAndNamespaceRule = new setNamespaceAndSchema(rootNodeLabel, xsi, schemaLoc)

// apply the rule with a new transformer
val newxml = new RuleTransformer(setSchemaAndNamespaceRule).transform(xml).head

应用转换器返回这个.

newxml: scala.xml.Node = 
  <root attr="willIStayOrWillIGoAway"     
        xmlns:ns="http://example.com/ns"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://example.com/ns http://example.com/xml/xsd/xml-schema-articles-v1.0.xsd">>
    <container/>
  </root>

这是返回重写规则的类.

And this is the class that returns the rewrite rule.

// new class that extends RewriteRule
class setNamespaceAndSchema(rootLabel: String, ns: NamespaceBinding, attrs: MetaData) extends RewriteRule {
  // create a RewriteRule that sets this as the only namespace
  override def transform(n: Node): Seq[Node] = n match {

    // ultimately, it's just a matter of setting the scope & attributes
    // on a new copy of the xml node
    case e: Elem if(e.label == rootLabel) =>
      e.copy(scope = ns, attributes = attrs.append(e.attributes))
    case n => n
  }
}

注意保留了我们原来的属性;查看我们扩展的 RewriteRule 类如何附加 schemaLocation 属性而不是直接使用它.

Notice that our original attribute is retained; check out how our extended RewriteRule class appends the schemaLocation attribute rather than using it directly.

这篇关于Scala RewriteRules 来设置命名空间 &amp;架构位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆