Scala RewriteRules设置命名空间&的schemaLocation?

时间:2016-09-08 16:08:27

标签: xml scala schema

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

<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">

看起来from this gist设置xmls:ns命名空间是创建NamespaceBinding并将其应用为Elem的范围。但是,我还没有为此成功创建RewriteRule,而且我仍在搜索如何添加模式实例(xmlns:xsi)和schemaLocation。

1 个答案:

答案 0 :(得分:0)

// 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,但因为它们是&#34;链接&#34;在一起,我们只需要将最后一个传递给我们的RuleTransformer类。

// 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

// 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>

这是返回重写规则的类。

// 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属性而不是直接使用它。