简体   繁体   中英

Xpath Case insensitive expression to get attributes from an XML

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.

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']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM