Correct namespace declaration in Java - java

I need to create an XML document with the following structure:
<?xml version="1.0" ?>
<Cancelacion xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
RfcEmisor="VSI850514HX4"
Fecha="2011-11-23T17:25:06"
xmlns="http://cancelacfd.sat.gob.mx">
<Folios>
<UUID>BD6CA3B1-E565-4985-88A9-694A6DD48448</UUID>
</Folios>
</Cancelacion>
The structure MUST be that way. But I'm not very familiar with the namespace declaration for the XML Elements. I can correctly generate an XML with the following structure:
<?xml version="1.0" ?>
<Cancelacion RfcEmisor="VSI850514HX4"
Fecha="2011-11-23T17:25:06"
xmlns="http://cancelacfd.sat.gob.mx">
<Folios>
<UUID>BD6CA3B1-E565-4985-88A9-694A6DD48448</UUID>
</Folios>
</Cancelacion>
But the problem is that I can't get to include the xmls:xsd and xmlns:xsi correctly. The code for properly generating the previously mentioned code is:
// Crear un document XML vacío
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
dbfac.setNamespaceAware(true);
DocumentBuilder docBuilder;
docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.newDocument();
doc.setXmlVersion("1.0");
doc.setXmlStandalone(true);
Element cancelacion = doc.createElementNS("http://cancelacfd.sat.gob.mx","Cancelacion");
cancelacion.setAttribute("RfcEmisor", rfc);
cancelacion.setAttribute("Fecha", fecha);
doc.appendChild(cancelacion);
Element folios = doc.createElementNS("http://cancelacfd.sat.gob.mx", "Folios");
cancelacion.appendChild(folios);
for (int i=0; i<uuid.length; i++) {
Element u = doc.createElementNS("http://cancelacfd.sat.gob.mx","UUID");
u.setTextContent(uuid[i]);
folios.appendChild(u);
}

You can add additional namespaces by calling setAttributeNS method on the root element
as shown in below example
// get the root element
Element rootElement = xmlDoc.getDocumentElement();
// add additional namespace to the root element
rootElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
You can then add elements to a given namespace by using the method like below
// append author element to the document element
Element author = xmlDoc.createElement("xsd:element");
Read this article for more details.

Related

Get element value from XML with XPath

I have XML file like this:
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents- xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 UBL-Invoice-2.1.xsd">
<cac:AccountingSupplierParty>
<cac:Party>
<cac:PartyIdentification>
<cbc:ID schemeID="schema1">123231123</cbc:ID>
</cac:PartyIdentification>
<cac:PartyIdentification>
<cbc:ID schemeID="schema2">2323232323</cbc:ID>
</cac:PartyIdentification>
<cac:PartyIdentification>
<cbc:ID schemeID="schema3">4442424</cbc:ID>
</cac:PartyIdentification>
<cac:PostalAddress>
<cbc:CityName>İstanbul</cbc:CityName>
<cac:Country>
<cbc:Name>Turkey</cbc:Name>
</cac:Country>
</cac:PostalAddress>
</cac:Party>
</cac:AccountingSupplierParty>
</Invoice>
I want to access schemeID="schema=2" value. I try XPath and document.getElementsByTagName. I can access elements with document.getElementsByTagName, since is multiple I can't access the element I want. When I try to with XPath, I can't access any elements from XML.
Here is my XPath implementation:
try {
String decoded = new
String(DatatypeConverter.parseBase64Binary(binaryXmlData));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(decoded));
Document doc = db.parse(is);
String expression = "/Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyIdentification/cbc:ID#[schemaID='schema2']/text()";
String schema2 = (String) xPath.compile(expression).evaluate(doc, XPathConstants.STRING);
System.out.println(schema2);
//schema2 is null
//Above this code block returns correct value
NodeList nl = doc.getElementsByTagName("cbc:CityName");
System.out.println(nl.item(0).getTextContent());
} catch () {
}
binaryXmlData is source of my XML. First, I convert base64binary data to xml. Am I doing to convertion wrong or my xpath implementation is wrong ?
There are many problems with your code and your XML, including:
Your XML is not well-formed. The closing quote of the cbc
namespace prefix is missing.
Your Java code never defines a NamespaceContext.
See also How does XPath deal with XML namespaces?

Get SOAP element by tag with namespace in Java

I wondered how it was possible to get the content of a SOAP response body child when the child tag looks like this:
<sth:x>...</sth:x>
In the Oracle docs I found how to loop all Elements with a specific name.
But therefore I need to create an Element first that specifies the name of the tag I want to search.
How do I create an element looking like the one above? I know how to make one like this:
<sth:id sth="asdf">
But that doesn't really work.
Here is the server-response I attempt to read.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<ns5:loginResponse xmlns:ns5="x">
<ns5:id>Value I am looking for</ns5:id>
<ns5:rc>0</ns5:rc>
</ns5:loginResponse>
</soapenv:Body>
</soapenv:Envelope>
Thanks for your help :)
Try this:
String xml = "YourXMl";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xml));
Document doc = builder.parse(is);
NodeList nodes = doc.getDocumentElement().getElementsByTagNameNS("x","id");
System.err.println(nodes.item(0).getChildNodes().item(0).getNodeValue());
There are two important things factory.setNamespaceAware(true); - to turn on support for xml namespaces.
doc.getDocumentElement().getElementsByTagNameNS("x","id"); To get element using namespace uri and element name. And here is <ns5:loginResponse xmlns:ns5="x"> declaration of namespace uri. x is uri ns5 is namespace.
I found the answer:
The Element in question was within another SOAPBodyElement.
So looping through both elements gave me the correct Value:
body = reply.getSOAPBody();
Iterator replyIt = body.getChildElements();
while(replyIt.hasNext()){
SOAPBodyElement replysbe = (SOAPBodyElement) replyIt.next();
Iterator replyIt2 = replysbe.getChildElements();
SOAPElement sentSE = (SOAPElement) replyIt2.next();
sessionID = sentSE.getValue();
}

How to get the attribute of a nested xml with namespace in java x path

I have an complex xml with nested structure and with namespace .
I am able to read the xml elements but not able to read the attribute .
Attribute Like i have to read contentSet or action from my xml .
Here is my XML structure
<?xml version="1.0"?>
<env:ContentEnvelope xsi:schemaLocation="http://fundamental.schemas.financial.jso.com/Fundamental/2011-07-07/
https://theshare.jso.com/sites/TRM-IA/Content%20Marketplace/Strategic%20Data%20Interfaces/SDI%20Schemas/Schemas/Fundamentals/2015-09-25/FundamentalMaster.xsd"
xmlns:esg="http://fundamental.schemas.financial.jso.com/ESGSupportingInfo/2011-07-07/"
xmlns:md="http://data.schemas.financial.jso.com/metadata/2010-10-10/"
xmlns:cr="http://fundamental.schemas.financial.jso.com/CoraxData/2012-10-25/"
<env:Header>
<env:Info>
<env:Id>urn:uuid:069527ab-2c10-48bb-b3d2-206f4e66e5d2</env:Id>
<env:TimeStamp>2016-12-23T10:09:09+00:00</env:TimeStamp>
</env:Info>
<fun:OrgId>20240</fun:OrgId>
<fun:PartitionId>1</fun:PartitionId>
</env:Header>
<env:Body minVers="0.0" majVers="1" contentSet="Fundamental">
<env:ContentItem action="Insert">
<env:Data xsi:type="fun:FundamentalDataItem">
<fun:Fundamental effectiveTo="9999-12-31T00:00:00+00:00" effectiveFrom="2013-06-29T00:55:15.313+00:00" uniqueFuamentalSet="0054341342">
<fun:OrganizationId objectType="Organization" objectTypeId="404510">42565596</fun:OrganizationId>
<fun:PrimaryReportingEntityCode>A4C67</fun:PrimaryReportingEntityCode>
<fun:TotalPrimaryReportingShares>567923000.00000</fun:TotalPrimaryReportingShares>
<fun:LocalLanguageId>505074</fun:LocalLanguageId>
<fun:IndustryGroups>
<fun:IndustryGroup validTo="9999-12-31T00:00:00+00:00" validFrom="1900-01-01T00:00:00+00:00">
<fun:GroupCode>BNK</fun:GroupCode>
<fun:GroupName languageId="505074">Bank</fun:GroupName>
<fun:TaxonomyId>1</fun:TaxonomyId>
<fun:IndustryGroupCodeId>3011649</fun:IndustryGroupCodeId>
</fun:IndustryGroup>
</fun:IndustryGroups>
<fun:GaapCode>CAG</fun:GaapCode>
<fun:ConsolidationBasis>Consolidated</fun:ConsolidationBasis>
<fun:IsFiling>true</fun:IsFiling>
<fun:ConsolidationBasisId>3013598</fun:ConsolidationBasisId>
<fun:GaapCodeId>3011536</fun:GaapCodeId>
<fun:Taxonomies>
<fun:Taxonomy>1</fun:Taxonomy>
</fun:Taxonomies>
<fun:WorldScopeIds>
<fun:WorldScopeId validTo="9999-12-31T00:00:00+00:00" validFrom="2012-03-31T00:00:00+00:00">C12436390</fun:WorldScopeId>
</fun:WorldScopeIds>
</fun:Fundamental>
</env:Data>
</env:ContentItem>
Here is my java sxpression to read that .
FileInputStream file = new FileInputStream(new File("c://temp/Fun.xml"));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
System.out.println("*************************");
String expression = "/ContentEnvelope/Body[#minVers='0.0']/contentSet";
System.out.println(expression);
Use #attribute_name syntax to reference attribute in XPath, just like you did with #minVers :
/ContentEnvelope/Body[#minVers='0.0']/#contentSet

XML Namespace - xmlns

I'm trying to generate a XML from Java.
Something like this:
<?xml version="1.0" encoding="UTF-8"?>
<ElementFile
xmlns="http://www.url.com/bla/bla"
xmlns:common="http://www.url.com/bla/bla/bla">
<Regulation>
<blablaElement>0000-0000</blablaElement>
</Regulation>
</ElementFile>
To do this, I wrote the following code:
ElementFile = document.addElement( "ElementFile" )
.addNamespace("xmlns","http://www.url.com/bla/bla")
.addNamespace("common", "http://www.url.com/bla/bla/bla");
But the generated code is:
<?xml version="1.0" encoding="UTF-8"?>
<ElementFile
xmlns:xmlns="http://www.url.com/bla/bla"
xmlns:common="http://www.url.com/bla/bla/bla">
<Regulation>
<blablaElement>0000-0000</blablaElement>
</Regulation>
</ElementFile>
However, if I write this (without xmlns)
ElementFile = document.addElement( "ElementFile" )
.addNamespace("","http://www.url.com/bla/bla")
.addNamespace("common", "http://www.url.com/bla/bla/bla");
Then, the xml generates the line properly but it adds xmlns=" " by default:
<?xml version="1.0" encoding="UTF-8"?>
<ElementFile
xmlns="http://www.url.com/bla/bla"
xmlns:common="http://www.url.com/bla/bla/bla">
<Regulation xmlns="">
<blablaElement>0000-0000</blablaElement>
</Regulation>
</ElementFile>
I'm quite lost...
[UPDATED QUESTION]
I'm sorry, but I don't understand how to integrated your answer in my code. I am new to this domain.
My complete code is:
XMLWriter writer = new XMLWriter(new FileWriter("xmlFileName"), format);
Document document = DocumentHelper.createDocument();
Element ElementFile = document.addElement( "ElementFile" )
.addNamespace("xmlns","http://www.url.com/bla/bla")
.addNamespace("xmlns:common", "http://www.url.com/bla/bla/bla");
Element Regulation = ElementFile.addElement( "Regulation" );
Element blablaElement = Regulation.addElement( "blablaElement" )
.addText( "0000-0000" );
writer.write(document);
writer.close();
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
dbfac.setNamespaceAware(true);
DocumentBuilder docBuilder;
docBuilder = dbfac.newDocumentBuilder();
DOMImplementation domImpl = docBuilder.getDOMImplementation();
Document doc = domImpl.createDocument("http://www.url.com/bla/bla", "ElementFile ", null);
doc.setXmlVersion("1.0");
doc.setXmlStandalone(true);
Element elementFile = doc.getDocumentElement();
elementFile.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:common","http://www.url.com/bla/bla/bla");
and add elements to this doc
you have a similar question here: How to create attribute (xmlns:xsd) to XML node in Java?

Reading XML within XML using Java

How to read From XML <returnMsg>Successful</returnMsg> value of this tag in java?
How to read the data of the tags in this example.
I am getting The processing instruction target matching "[xX][mM][lL]" is not allowed. Exception is getting
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<doServiceResponse xmlns="http://ocs.ztesoft.com">
<doServiceReturn><?xml version="1.0" encoding="UTF-8"?>
<zsmart>
<Data>
<header>
<returnMsg>Successful</returnMsg>
<ACTION_ID>ModifyBalReturnAllBal</ACTION_ID>
<REQUEST_ID>0032013070900000503</REQUEST_ID>
<returnCode>0</returnCode>
</header>
<body>
<TransactionSN>503</TransactionSN>
</body>
</Data>
</zsmart>
</doServiceReturn></doServiceResponse></soapenv:Body></soapenv:Envelope>
JAVA CODE
dbf = DocumentBuilderFactory.newInstance();
db = dbf.newDocumentBuilder();
is = new InputSource();
is.setCharacterStream(new StringReader(respString));
doc = db.parse(is);
nodes = doc.getElementsByTagName("soapenv:Envelope");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList txnStatus = element.getElementsByTagName("returnCode");
Element line = (Element) txnStatus.item(0);
bean.setTxnStatus(getCharacterDataFromElement(line));
NodeList message = element.getElementsByTagName("returnMsg");
line = (Element) message.item(0);
bean.setMessage(getCharacterDataFromElement(line));
}
Exception
org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.
There are many way to convert XML file to JAVA OBJECT.
SAX and JAXB algorithms are two of them.
JAXB algorithm is more easily to use. i prefer to use JAXB.
HERE is the link that helps you to create Object from XML file.
enjoy it...
http://www.mkyong.com/java/jaxb-hello-world-example/

Categories

Resources