Reputation: 168
Cunrrently im reading some XML
files and extracting some values using some predefined paths with the Help of Xpath
The paths look like this:
Comprobante/@Fecha
the path above for example would be used to extract the attribute @Fecha
, the file looks something like this:
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" Fecha="2017-10-25T19:13:19">
</cfdi:Comprobante>
Here´s an example of the code im using to get the data, in this case I will be getting the value of the attribue @Fecha
.
Code Example
File inputFile = new File(file);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(inputFile);
doc.getDocumentElement().normalize();
XPath xPath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xPath.compile("Comprobante/@Fecha")
String names = (String) expr.evaluate(doc, XPathConstants.STRING);
As far as I know XML files are case sensitive, the files I have been reading always had @Fecha
with the letter F
in caps, but recently I received a lot of files with @fecha
instead of @Fecha
in addition to the usual files with @Fecha
, I can´t control how the files are written at the moment so I need to find a workaround for this problem because the code I have returns null
when applied to the files that have @fecha
Example of a file with @fecha
:
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" fecha="2017-10-25T19:13:19">
</cfdi:Comprobante>
I could do an if
statement and check if the value Im getting is empty
and then check again but with @fecha
instead of @Fecha
, like so:
File inputFile = new File(file);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(inputFile);
doc.getDocumentElement().normalize();
XPath xPath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xPath.compile("Comprobante/@Fecha")
String names = (String) expr.evaluate(doc, XPathConstants.STRING);
if(names.isEmpty()){
XPathExpression expr = xPath.compile("Comprobante/@fecha")
String names = (String) expr.evaluate(doc, XPathConstants.STRING);
}
But I would like to know if there is a way to do this with a Xpath Expression
that gets the value of @Fecha
regardless of the size of letter F
,instead of the IF
expression, I found that I can do it using the function translate
, something like:
translate(@Fecha, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')
But I cant seem to make it work.
Upvotes: 1
Views: 1612
Reputation: 111541
Your XPath,
translate(@Fecha, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')
translates the @Fecha
attribute value to lower case.
This XPath 1.0,
Comprobante/@*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')
= 'fecha']
selects the attribute of Comprobante
whose name in lower-case is fecha
.
Or more concisely in XPath 2.0:
Comprobante/@*[lower-case(local-name()) = 'fecha']
Upvotes: 3