Java 如何将支持XInclude的XMLReader链接到XMLFilter,以便对过滤器已更改的任何元素执行XInclude包含?
在海报中,我们想使用XInclude,但在Java 如何将支持XInclude的XMLReader链接到XMLFilter,以便对过滤器已更改的任何元素执行XInclude包含?,java,xml,sax,xerces2-j,Java,Xml,Sax,Xerces2 J,在海报中,我们想使用XInclude,但在include元素上使用了错误的名称空间。我认为,在XInclude感知解析器之前放置一个put,XMLFilter负责更正名称空间,可以解决这个问题(无需分别手动编辑文件,无需单独的处理步骤,首先创建具有更正名称空间的中间文件) 因此,我编写了以下XMLFilter,扩展了SAX提供的XMLFilterImpl: import org.xml.sax.Attributes; import org.xml.sax.SAXException; import
include
元素上使用了错误的名称空间。我认为,在XInclude感知解析器之前放置一个put,XMLFilter负责更正名称空间,可以解决这个问题(无需分别手动编辑文件,无需单独的处理步骤,首先创建具有更正名称空间的中间文件)
因此,我编写了以下XMLFilter
,扩展了SAX提供的XMLFilterImpl
:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.XMLFilterImpl;
public class XIncludeNsFixup extends XMLFilterImpl {
static String correctURI = "http://www.w3.org/2001/XInclude";
static String oldURI = "http://www.w3.org/2003/XInclude";
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
if (uri.equals(oldURI)) {
super.startElement(correctURI, localName, qName, atts);
}
else {
super.startElement(uri, localName, qName, atts);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (uri.equals(oldURI)) {
super.endElement(correctURI, localName, qName);
}
else {
super.endElement(uri, localName, qName);
}
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
if (uri.equals(oldURI)) {
super.startPrefixMapping(prefix, correctURI);
}
else {
super.startPrefixMapping(prefix, uri);
}
}
}
然后,我分别创建了一个支持XInclude的SAXParserXMLReader
链接到该过滤器,并将示例文档作为SAXSource
从该过滤器加载到默认的Transformer
中,以构建DOMResult
:
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setXIncludeAware(true);
XMLReader inputReader = spf.newSAXParser().getXMLReader();
XMLFilter fixNs = new XIncludeNsFixup();
fixNs.setParent(inputReader);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer builder = tf.newTransformer();
DOMResult fixedInput = new DOMResult();
builder.transform(new SAXSource(fixNs, new InputSource("file3.xml")), fixedInput);
Document doc = (Document) fixedInput.getNode();
Transformer serializer = tf.newTransformer();
serializer.transform(new DOMSource(doc), new StreamResult(System.out));
我使用的示例文档file3.xml
在适当的xinclude命名空间中有一个xi:xinclude
元素,在旧的不受支持的命名空间中有一个元素:
<?xml version="1.0" encoding="UTF-8"?>
<contexts>
<context name="a">
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="reuse.xml"/>
<foo>Original text 1.</foo>
</context>
<context name="b">
<xi:include xmlns:xi="http://www.w3.org/2003/XInclude" href="reuse.xml"/>
<foo>Original text 2.</foo>
</context>
</contexts>
以及Java程序的完整代码,以便于测试:
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;
public class XIncludeTest1 {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerConfigurationException, TransformerException {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setXIncludeAware(true);
XMLReader inputReader = spf.newSAXParser().getXMLReader();
XMLFilter fixNs = new XIncludeNsFixup();
fixNs.setParent(inputReader);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer builder = tf.newTransformer();
DOMResult fixedInput = new DOMResult();
builder.transform(new SAXSource(fixNs, new InputSource("file3.xml")), fixedInput);
Document doc = (Document) fixedInput.getNode();
Transformer serializer = tf.newTransformer();
serializer.transform(new DOMSource(doc), new StreamResult(System.out));
}
}
我还尝试将来自Apache的最新Xerces Java放在类路径上,以查看它是否解决了问题,但输出保持不变
<?xml version="1.0" encoding="UTF-8"?>
<text>I am XIncluded text.</text>
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;
public class XIncludeTest1 {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerConfigurationException, TransformerException {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setXIncludeAware(true);
XMLReader inputReader = spf.newSAXParser().getXMLReader();
XMLFilter fixNs = new XIncludeNsFixup();
fixNs.setParent(inputReader);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer builder = tf.newTransformer();
DOMResult fixedInput = new DOMResult();
builder.transform(new SAXSource(fixNs, new InputSource("file3.xml")), fixedInput);
Document doc = (Document) fixedInput.getNode();
Transformer serializer = tf.newTransformer();
serializer.transform(new DOMSource(doc), new StreamResult(System.out));
}
}