Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jaxb在解组时忽略名称空间_Java_Spring_Jaxb - Fatal编程技术网

Java Jaxb在解组时忽略名称空间

Java Jaxb在解组时忽略名称空间,java,spring,jaxb,Java,Spring,Jaxb,我使用Jaxb2和Spring。我正在尝试解组我的两个客户发送的一些XML 到目前为止,我只需要处理一个客户发送的xml如下: <foo xmlns="com.acme"> <bar>[...]</bar> <foo> @XmlType(name = "", propOrder = {"bar"}) @XmlRootElement(name = "Foo") public class Foo { @XmlElement(name = "

我使用Jaxb2和Spring。我正在尝试解组我的两个客户发送的一些XML

到目前为止,我只需要处理一个客户发送的xml如下:

<foo xmlns="com.acme">
  <bar>[...]</bar>
<foo>
@XmlType(name = "", propOrder = {"bar"})
@XmlRootElement(name = "Foo")
public class Foo {

  @XmlElement(name = "Bar")
  private String bar;

  [...]
}
我发现之前的开发人员在解组器中硬编码了名称空间以使其工作

现在,第二个客户发送相同的XML,但更改了名称空间

<foo xmlns="com.xyz">
  <bar>[...]</bar>
<foo>
似乎唯一可用的选项是Jaxb2Marshaller的Javadoc中列出的选项:

/**
 * Set the JAXB {@code Marshaller} properties. These properties will be set on the
 * underlying JAXB {@code Marshaller}, and allow for features such as indentation.
 * @param properties the properties
 * @see javax.xml.bind.Marshaller#setProperty(String, Object)
 * @see javax.xml.bind.Marshaller#JAXB_ENCODING
 * @see javax.xml.bind.Marshaller#JAXB_FORMATTED_OUTPUT
 * @see javax.xml.bind.Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION
 * @see javax.xml.bind.Marshaller#JAXB_SCHEMA_LOCATION
 */
public void setMarshallerProperties(Map<String, ?> properties) {
    this.marshallerProperties = properties;
}
3)SAXParser的不同形式:

try {
  jc = JAXBContext.newInstance("com.mycompany.mypkg");
  Unmarshaller um = jc.createUnmarshaller();
  final SAXParserFactory sax = SAXParserFactory.newInstance();
  sax.setNamespaceAware(false);
  final XMLReader reader = sax.newSAXParser().getXMLReader();
  final Source er = new SAXSource(reader, new InputSource(new FileReader(xmlFile.toFile())));
  return (Foo)um.unmarshal(er);
}catch(...) {[...]}

这个有效但是,我还是希望能够自动连接解组器,而不需要每次都使用这种难看的配置。

名称感知是文档阅读器/生成器/解析器的功能,而不是封送器的功能。来自不同名称空间的XML元素表示不同的实体==对象,因此封送处理程序不能忽略它们

您正确地关闭了SAX读取器中的名称空间,正如您所说,它工作正常。我不理解你的问题,你的封送员仍然可以被注入,区别在于获取输入数据

使用document builder的相同技巧也应该有效(稍后我将对其进行测试),我怀疑您仍然使用带有“硬编码”命名空间的封送器,但您的文档没有命名空间

在我的项目中,我使用XSLT来解决类似的问题。设置名称空间感知绝对是更容易的解决方案。但是,使用XSLT,我可以选择只删除一些名称空间,而且我的输入xml并不总是相同的(忽略名称空间),有时我不得不重命名一些元素,因此XSLT给了我额外的灵活性

要删除名称空间,可以使用以下xslt模板:


然后在Java中,在解组之前,我转换输入数据:

Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
Source source = new DOMSource(xml);
DOMResult result = new DOMResult();
transformer.transform(source, result);

谢谢大家,这里分享了我的解决方案,它适用于我的代码,我尝试使它成为通用的每个名称空间包含“:“如果任何标记有,我编写代码”:“它将从xml中删除,这用于在使用jaxb解组期间跳过名称空间

public class NamespaceFilter {

private NamespaceFilter() {

}

private static final String COLON = ":";

public static XMLReader nameSpaceFilter() throws SAXException {
    XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
        private boolean skipNamespace;

        @Override
        public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
            if (qName.indexOf(COLON) > -1) {
                skipNamespace = true;
            } else {
                skipNamespace = false;
                super.startElement("", localName, qName, atts);
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if (qName.indexOf(COLON) > -1) {
                skipNamespace = true;
            } else {
                skipNamespace = false;
                super.endElement("", localName, qName);
            }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            if (!skipNamespace) {
                super.characters(ch, start, length);
            }
        }
    };
    return xr;
}
}

拆封

XMLReader xr = NamespaceFilter.nameSpaceFilter();
Source src = new SAXSource(xr, new InputSource("C:\\Users\\binal\\Desktop\\response.xml"));
StringWriter sw = new StringWriter();
Result res = new StreamResult(sw);
TransformerFactory.newInstance().newTransformer().transform(src, res);
JAXBContext jc = JAXBContext.newInstance(Tab.class);
Unmarshaller u = jc.createUnmarshaller();
String done = sw.getBuffer().toString();
StringReader reader = new StringReader(done);
Tab tab = (Tab) u.unmarshal(reader);

System.out.println(tab);
`

public class NamespaceFilter {

private NamespaceFilter() {

}

private static final String COLON = ":";

public static XMLReader nameSpaceFilter() throws SAXException {
    XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
        private boolean skipNamespace;

        @Override
        public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
            if (qName.indexOf(COLON) > -1) {
                skipNamespace = true;
            } else {
                skipNamespace = false;
                super.startElement("", localName, qName, atts);
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if (qName.indexOf(COLON) > -1) {
                skipNamespace = true;
            } else {
                skipNamespace = false;
                super.endElement("", localName, qName);
            }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            if (!skipNamespace) {
                super.characters(ch, start, length);
            }
        }
    };
    return xr;
}
XMLReader xr = NamespaceFilter.nameSpaceFilter();
Source src = new SAXSource(xr, new InputSource("C:\\Users\\binal\\Desktop\\response.xml"));
StringWriter sw = new StringWriter();
Result res = new StreamResult(sw);
TransformerFactory.newInstance().newTransformer().transform(src, res);
JAXBContext jc = JAXBContext.newInstance(Tab.class);
Unmarshaller u = jc.createUnmarshaller();
String done = sw.getBuffer().toString();
StringReader reader = new StringReader(done);
Tab tab = (Tab) u.unmarshal(reader);

System.out.println(tab);