开放/封闭原则规定软件实体(类,模块等)应该是可以扩展的,但是对于修改是封闭的.这意味着什么,为什么它是良好的面向对象设计的重要原则?
oop definition design-principles open-closed-principle solid-principles
我正在处理一个已经创建的 Document对象.我必须能够将它的基本命名空间(属性名称"xmlns")设置为特定值.我的输入是DOM,类似于:
<root>...some content...</root>
Run Code Online (Sandbox Code Playgroud)
我需要的是DOM,它类似于:
<root xmlns="myNamespace">...some content...</root>
Run Code Online (Sandbox Code Playgroud)
而已.容易,不是吗?错误!没有DOM!
我得到一个空xmlns的文档(它适用于任何其他属性名称!)
<root xmlns="">...</root>
Run Code Online (Sandbox Code Playgroud)
首先克隆文档:
Document input = /*that external Document whose namespace I want to alter*/;
DocumentBuilderFactory BUILDER_FACTORY_NS = DocumentBuilderFactory.newInstance();
BUILDER_FACTORY_NS.setNamespaceAware(true);
Document output = BUILDER_NS.newDocument();
output.appendChild(output.importNode(input.getDocumentElement(), true));
Run Code Online (Sandbox Code Playgroud)
我真的很想念document.clone(),但也许只是我.
现在重命名根节点:
output.renameNode(output.getDocumentElement(),"myNamespace",
output.getDocumentElement().getTagName());
Run Code Online (Sandbox Code Playgroud)
现在不是那么简单吗?;)
我现在得到的是:
<root xmlns="myNamespace">
<someElement xmlns=""/>
<someOtherElement xmlns=""/>
</root>
Run Code Online (Sandbox Code Playgroud)
那么(正如我们所有人所期望的那样,对吧?),这只重命名根节点的命名空间.
诅咒你,DOM!
有没有办法以递归方式执行此操作(无需编写自己的递归方法)?
请不要建议我做一些花哨的解决方法,例如将DOM转换为其他内容,在那里更改命名空间,然后将其转换回来.我需要DOM,因为它是操作XML的最快标准方法.
注意:我正在使用最新的JDK.
编辑
从问题中删除了错误的假设,这与假名前缀有关.
我正在尝试将ResultSet转换为XML文件.我首先使用这个例子进行序列化.
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.Document;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
...
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
DOMImplementationLS impl =
(DOMImplementationLS)registry.getDOMImplementation("LS");
...
LSSerializer writer = impl.createLSSerializer();
String str = writer.writeToString(document);
Run Code Online (Sandbox Code Playgroud)
在我完成这项工作后,我尝试验证我的XML文件,有几个警告.一个关于没有doctype的人.所以我尝试了另一种方法来实现它.我遇到了Transformer课程.这个类让我设置编码,doctype等.
以前的实现支持自动命名空间修复.以下不是.
private static Document toDocument(ResultSet rs) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
URL namespaceURL = new URL("http://www.w3.org/2001/XMLSchema-instance");
String namespace = "xmlns:xsi="+namespaceURL.toString();
Element messages = doc.createElementNS(namespace, "messages");
doc.appendChild(messages);
ResultSetMetaData rsmd = rs.getMetaData();
int colCount = rsmd.getColumnCount();
String attributeValue = "true";
String attribute = …Run Code Online (Sandbox Code Playgroud) 在给定w3c DOM(Java的默认实现,特别是)更改该DOM中每个元素/属性/节点的命名空间的情况下,我该怎么办?有效地,优选地.DOM上似乎没有setNamespaceURI方法,这很不方便.
我已经尝试过XSL方法,但它们无法在JAXP变换器中工作(尽管它们在Saxon9B中可以正常工作,但由于其他各种原因我无法使用它).
基本上,我需要一个纯粹的核心java解决方案,它允许我获取一个文档并更改其命名空间.
我正在尝试使用以下代码片段来编组消息:
JAXBContext jContext = JAXBContext.newInstance(Iq.class);
Marshaller m = newJAXBContext.createMarshaller();
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Bind bind = new Bind();
bind.setResource("resource");
Iq iq = new Iq();
iq.setId(iqId);
iq.setType("set");
iq.getAnies().add(bind);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
m.marshal(iq, baos);
Run Code Online (Sandbox Code Playgroud)
这里,Iq和Bind是由相关的xmpp模式形成的对象.我的问题是,使用jaxb 2.0及更高版本,所有命名空间都在根元素中声明:
<iq from='juliet@example.com/balcony'
id='rg1'
type='get' xmlns='jabber:client' xmlns:ns1='urn:ietf:params:xml:ns:xmpp-bind'>
<ns1:bind>
<ns1:resource>resource</ns1:resource>
</ns1:bind>
</iq>
Run Code Online (Sandbox Code Playgroud)
但是,这里需要的是命名空间应该占用适当的位置:
<iq from='juliet@example.com/balcony'
id="rg1"
type="get" xmlns="jabber:client">
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
<resource>resource</resource>
</bind>
</iq>
Run Code Online (Sandbox Code Playgroud)
有没有办法通过JAXB 2.0或更高版本在第二个xml节中看到它们来编组xmpp节?
长话短说,我在这里有两个问题:1.在适当的位置声明命名空间.2.删除我理解的名称空间前缀可以使用NamespacePrefixMapper删除?但不确定,一个例子会很棒.
java ×4
xml ×3
dom ×2
definition ×1
document ×1
jaxb ×1
marshalling ×1
namespaces ×1
oop ×1
xmpp ×1