I have this string with xml extract in a tuple list:
MessageResponse = [{"code",0},{"description","description"},{"respuestaServicioSoap",{{"executeWebServiceSolutionResult",{{"CEDULARUCSpecified", false},{"AUTORIZACION", "00000012431781"},{"AUTORIZACIONSpecified",true},{"RESULTADO","000"},{"CODIGO_RESULTADOSpecified",true},{"COD_PAGO","00000012431781"},{"COD_PAGOSpecified",true},{"COMISION",{{"string","0"}}},{"COMISIONSpecified", true},{"DIRECCIONSpecified", false},{"FECHA_COMPENSACIONSpecified", false},{"FECHA_TRANSACCION","20170116"},{"FECHA_TRANSACCIONSpecified",true},{"FECHORA_SW","20170116123951"},{"FECHORA_SWSpecified",true},{"HORA_TRANSACCION","123951"},{"HORA_TRANSACCIONSpecified",true},{"MENSAJE","TRANSACCION OK"},{"MENSAJESpecified",true},{"NOMBRESpecified",false},{"PRODUCTO","0010761005"},{"PRODUCTOSpecified",true},{"SECUENCIA_ADQ","2833"},{"SECUENCIA_ADQSpecified",true},{"SECUENCIA_SW","576167"},{"SECUENCIA_SWSpecified",true},{"TERMINAL","0696069603000001"},{"TERMINALSpecified",true},{"TYPE_TRNSpecified",false},{"VALOR_TOTAL", { { "string", "0" }}},{"VALOR_TOTALSpecified",true},{"XML_ADDSpecified",false},{"XML_DATASpecified",false},{"XML_FACT","<XML_FACT>\r\n <DATOS_FACT>\r\n <LINEA_1>REPRESENTACIONES ORMAN S.A.</LINEA_1>\r\n <LINEA_2>RUC: 0987654321</LINEA_2>\r\n <LINEA_3 />\r\n <LINEA_4 />\r\n <LINEA_5>FACTURA: 001-627-0000048745</LINEA_5>\r\n <LINEA_6>CLAVE: </LINEA_6>\r\n <LINEA_7>COMISION POR SERVICIO</LINEA_7>\r\n <LINEA_8>RECAUDACION EEAAPP - CUENTA: 11223344</LINEA_8>\r\n <LINEA_12>FACTURA: 001-627-0000048745 - CONSULTE SU DOCUMENTO EN WWW.LITO.COM/DOCUMENTOSELECTRONICOS</LINEA_12>\r\n <MSGCOMP />\r\n <MSGFACT />\r\n </DATOS_FACT>\r\n</XML_FACT>"},{"XML_FACTSpecified",true},{"XML_REPLY_CONSULTASpecified",false},{"XML_REPLY_PAGOSSpecified",false}}},{"executeWebServiceSolutionResultSpecified", true}}},{"result", "ok"}]
and need to get the text in LINEA_5 tag, any idea how to do it?
with this code:
{Xml, _Rest} = xmerl_scan:string(XmlFactura).
[#xmlText{value=Linea5}] = xmerl_xpath:string("//LINEA_5/text()", Xml).
the OTP library xmerl provides all the functions to manipulate XML files or string. It provides a set of record that help to handle different elements.
documentation is available here
The records are defined in erlXX/lib/xmerl-YYY/include/xmerl.hrl:
#xmlText{}
#xmlElement{}
#xmlPI{}
#xmlComment{}
#xmlDecl{}
[edit]
The xml data that you provide in your example is already modified, so I take an example from my own. Consider an xml file with the content:
<?xml version="1.0" encoding="UTF-8"?> <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="uuid_id">
<metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:opf="http://www.idpf.org/2007/opf" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:calibre="http://calibre.kovidgoyal.net/2009/metadata" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:creator opf:role="aut" opf:file-as="Ahern, Cecelia">Cecelia Ahern</dc:creator>
<dc:publisher>J'ai Lu</dc:publisher>
<meta name="calibre:title_sort" content="Si tu me voyais maintenant"/>
<dc:description>description blah blah</dc:description>
<meta name="calibre:timestamp" content="2012-03-18T18:04:20+00:00"/>
<dc:title>Si tu me voyais maintenant</dc:title>
<meta name="cover" content="cover"/>
<dc:date>2012-03-18T18:04:23+00:00</dc:date>
<dc:contributor opf:role="bkp">calibre (0.8.42) [http://calibre-ebook.com]</dc:contributor>
<dc:identifier opf:scheme="ISBN">9782290006504</dc:identifier>
<dc:identifier id="uuid_id" opf:scheme="uuid">7d062b17-258e-4268-9d46-a753c063c969</dc:identifier>
<dc:subject>Chick-lit</dc:subject>
<meta name="calibre:user_categories" content="{}"/>
<meta name="calibre:author_link_map" content="{"Cecelia Ahern": ""}"/>
<dc:language>fr</dc:language>
</metadata>
<manifest>
<item href="cover.jpeg" id="cover" media-type="image/jpeg"/>
</manifest>
<spine toc="ncx">
<itemref idref="titlepage"/>
</spine>
<guide>
<reference href="titlepage.xhtml" type="cover" title="Cover"/>
</guide> </package>
It is extract from an epub book, and stored in a file "content.opf". If I want to get the author name (line 4) I can do:
1> rr("C:\\My programs\\erl8.2\\lib\\xmerl-1.3.12\\include\\xmerl.hrl").
2> {Xml,_} = xmerl_scan:file("../doc/content.opf"),
2> Content = Xml#xmlElement.content,
2> [MetaRec] = [X || X <- Content, X#xmlElement.name == metadata],
2> Meta = MetaRec#xmlElement.content,
2> [CreatRec] = [X || X <- Meta, X#xmlElement.name == 'dc:creator'],
2> Creat = CreatRec#xmlElement.content,
2> [CreatText] = [X || X <- Creat, is_record(X,xmlText)],
2> Aut = CreatText#xmlText.value.
"Cecelia Ahern"
I am trying to convert and XML to an XML using XSLT 2.0 in saxon/java. I am using a sample XML I found on stack overflow thread "Applying Muenchian grouping for a simple XML with XSLT"
However I am getting an error : XPDY0002: The context item for axis step ./CLIENT is absent.
My test XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="CLIENTS" name="main">
<CLIENTS>
<xsl:for-each-group select="CLIENT" group-by="NAME">
<xsl:comment><xsl:value-of select="current-grouping-key()"/> </xsl:comment>
<CLIENT>
<xsl:sequence select="NAME" />
<xsl:for-each select="current-group()">
<ACCOUNT>
<xsl:sequence select="*[not(self::NAME)]" />
</ACCOUNT>
</xsl:for-each>
</CLIENT>
</xsl:for-each-group>
</CLIENTS>
</xsl:template>
</xsl:stylesheet>
My Test XML:
<CLIENTS>
<CLIENT>
<NAME>John</NAME>
<ACCOUNT_NUMBER>1424763562761</ACCOUNT_NUMBER>
<LAST_USED>2012-10-03</LAST_USED>
<AMOUNT>5000</AMOUNT>
</CLIENT>
<CLIENT>
<NAME>John</NAME>
<ACCOUNT_NUMBER>543667543732</ACCOUNT_NUMBER>
<LAST_USED>2012-10-02</LAST_USED>
<AMOUNT>10000</AMOUNT>
</CLIENT>
</CLIENTS>
My Java ( which works with other transforms) :
void xmlXSLTParser(){
String xslFile = commonPath + "/xslt/inputPointCSVTOXML_style2.xsl";
String inputFile = "file:///" + commonPath + pointWorkFile;
String outputFile = commonPath + pointWorkFile + ".final";
try {
Processor proc = new Processor(false);
XsltCompiler comp = proc.newXsltCompiler();
XsltExecutable exp = comp.compile(new StreamSource(new File(xslFile)));
Serializer out = new Serializer();
out.setOutputProperty(Serializer.Property.METHOD, "xml");
out.setOutputProperty(Serializer.Property.INDENT, "yes");
out.setOutputFile(new File(outputFile));
XsltTransformer trans = exp.load();
trans.setInitialTemplate(new QName("main"));
//trans.setParameter(new QName("url-of-csv"),new XdmAtomicValue(inputFile));
trans.setDestination(out);
trans.transform();
System.out.println("Output written to text file");
} catch (SaxonApiException e) {
println("XSLT Error :" + e );
}
}
}
My Error in detail:
Error at char 6 in xsl:for-each-group/#select on line 10 column 59 of inputPointCSVTOXML_style2.xsl:
XPDY0002: The context item for axis step ./CLIENT is absent
XSLT Error :net.sf.saxon.s9api.SaxonApiException: The context item for axis step ./CLIENT is absent
Your Java code does not set any context item, instead it sets an initial template. So you will need to make sure you provide the input XML as the context item to the XsltTransformer, using http://saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/XsltTransformer.html#setInitialContextNode(net.sf.saxon.s9api.XdmNode) or as a Source, using http://saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/XsltTransformer.html#setSource(javax.xml.transform.Source).
So instead of trans.setInitialTemplate(new QName("main")); use trans.setSource(new StreamSource(inputFile));.
I am attempting to implement a Quickbooks Web connector (QBWC) in Railo 4.x
<cfcomponent output="false">
<cffunction name = "authenticate" access="remote" returntype="string">
<cfargument name = "username" type="string" required="true">
<cfargument name = "password" type = "string" required="true">
<cfset var loc = {}>
<cfset loc.retVal= []>
<cfset loc.retVal[1] = "MYSESSIONTOKEN">
<cfset loc.retVal[2] = "NONE">
<cfset loc.retVal[3] = "">
<cfset loc.retVal[4] = "">
<cfreturn loc.retVal >
</cffunction>
<cffunction name = "clientVersion" access="remote" returnType ="string">
<cfargument name = "productVersion" type="string" required="true">
<cfset var loc = {}>
<cfset loc.retVal = "">
<cfreturn loc.retVal>
</cffunction>
</cfcomponent>
This is my QWC file:
<?xml version="1.0"?>
<QBWCXML>
<AppName>QuickCellarSVC</AppName>
<AppID></AppID>
<AppURL>http://localhost:8080/QuickCellar.cfc</AppURL>
<AppDescription>Quick Cellar railo component</AppDescription>
<AppSupport>http://localhost:8080/support.cfm</AppSupport>
<UserName>Joe</UserName>
<OwnerID>{57F3B9B1-86F1-4fcc-B1EE-566DE1813D20}</OwnerID>
<FileID>{90A44FB5-33D9-4815-AC85-BC87A7E7D1EB}</FileID>
<QBType>QBFS</QBType>
<Scheduler>
<RunEveryNMinutes>2</RunEveryNMinutes>
</Scheduler>
</QBWCXML>
The QBWC trace shows the problem :
Object reference not set to an instance of an object.
More info:
StackTrace = at QBWebConnector.WebService.do_authenticate(String& ticket, String& companyFileName)
Source = QBWebConnector
I was able to drill down a little more and discover that there is a casting problem in Railo maybe?
<?xml version="1.0" encoding="UTF-8"?>
-<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">-<soap:Body>-
Can't cast Complex Object Type Struct to StringUse Built-In-Function "serialize(Struct):String" to create a String from Struct
Now I know some of you are thinking "just serialize" the struct. Well, there is no such function in Railo (that I know of).
Any ideas are greatly appreciated.
The first issue I see is your "authenticate" method has return type of string, but you are returning an array. If you are trying to return a string you could use return serializeJSON(loc.retVal) instead of just retVal, which would return it as a JSON formatted string.
I have below payload ,where I have to count number of child elements under <Document>.
For example:
<Document>
<Class>D</Class>`enter code here`
<ClassDescription>Drawings</ClassDescription>
<ClientDocumentNumber>12345</ClientDocumentNumber>
<Document>
The count will be 3.
The Payload is as below. Check this code.
<?xml version="1.0" encoding="UTF-8"?>
<InputVariable>
<part name="payload">
<ProjectMessage>
<ConversationId>E53252F709653493E0401E0A13916A2E</ConversationId>
<SourceApplicationId>Convero</SourceApplicationId>
<Operation>INS DOC</Operation>
<ModifiedByUserEmail>daviD.Woo#xyz.com</ModifiedByUserEmail>
<Project>
<Id>100020</Id>
<DocumentList>
<Document>
<Class>D</Class>
<ClassDescription>Drawings</ClassDescription>
<ClientDocumentNumber>12345</ClientDocumentNumber>
<ClientRevisionNumber>2.0</ClientRevisionNumber>
<Discipline>141</Discipline>
<DisciplineDescription>ACN</DisciplineDescription>
<Facility>24</Facility>
<Number>100020-24-140-SKT-0002</Number>
<OSROriginator>086238</OSROriginator>
<Revision>2.0</Revision>
<RevisionDate>2013-02-11T00:00:00Z</RevisionDate>
<Status>A</Status>
<StatusDescription>Active</StatusDescription>
<SupplierDocumentNumber>523570.000</SupplierDocumentNumber>
<SupplierRevisionNumber>CCC</SupplierRevisionNumber>
<Title>Test for FileNet</Title>
<Type>NA</Type>
<TypeDescription>NA</TypeDescription>
</Document>
</DocumentList>
</Project>
</ProjectMessage>
</part>
</InputVariable>
<xsl:template match="Document">
<xsl:value-of select="count(*)"/>
</xsl:template>
is a template matching Document elements and counting the child elements.
How to get xpath for rc an element returned by search
f=File.open('/media/cc.xml')
doc = Nokogiri::XML f
rc = doc.search('realmCode')
[#<Nokogiri::XML::Element:0x15a4d714 name="realmCode" namespace=#<Nokogiri::XML::Namespace:0x15a4dafc href="urn:hl7-org:v3"> attributes=[#<Nokogiri::XML::Attr:0x15a4d5c0 name="code" value="US">]>]
Is there a way to extract xpath from rc ?
updated with xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/ccda.xsl"?>
<ClinicalDocument xmlns:sdtc="urn:hl7-org:sdtc" xmlns:vocdo="urn:hl7-org:v3/voc" xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mif="urn:hl7-org:v3/mif">
<realmCode code="US"/>
<typeId root="2.16.840.1.113883.1.3" extension="POCD_HD000040"/>
<templateId root="2.16.840.1.113883.10.20.22.1.1"/>
<templateId root="2.16.840.1.113883.10.20.22.1.2"/>
<id root="2.16.840.1.113883.19.5.99999.1" extension="Test CCDA"/>
<code codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" code="34133-9" displayName="Summarization of Episode Note"/>
<title>Continuity of Care Document (C-CDA)</title>
<effectiveTime value="20130809043133+0000"/>
<confidentialityCode codeSystem="2.16.840.1.113883.5.25" codeSystemName="HL7 Confidentiality" code="N" displayName="Normal"/>
<languageCode code="en-US"/>
<recordTarget>
<patientRole>
<id root="2.16.840.1.113883.4.6" extension="1"/>
<id root="2.16.840.1.113883.4.1" extension="123-101-5230"/>
<addr use="HP">
<streetAddressLine>1357 Amber Drive</streetAddressLine>
<city nullFlavor="UNK"/>
<state nullFlavor="UNK"/>
<postalCode>97006</postalCode>
<country nullFlavor="UNK"/>
</addr>
<telecom value="3545345" use="HP"/>
<patient>
<name use="L">
<given qualifier="BR">test</given>
<family qualifier="CL">overall</family>
<prefix qualifier="IN">Mr</prefix>
</name>
<administrativeGenderCode codeSystem="2.16.840.1.113883.5.1" codeSystemName="HL7 AdministrativeGender" code="M" displayName="Male"/>
<birthTime value="19770429"/>
<raceCode codeSystem="2.16.840.1.113883.6.238" codeSystemName="Race and Ethnicity - CDC" code="2028-9" displayName="Asian"/>
<ethnicGroupCode codeSystem="2.16.840.1.113883.6.238" codeSystemName="Race and Ethnicity - CDC" code="2135-2" displayName="Hispanic or Latino"/>
<languageCommunication>
<languageCode code="eng"/>
<preferenceInd value="true"/>
</languageCommunication>
</patient>
</patientRole>
</recordTarget>
</ClinicalDocument>
rc is not an element-it's an array of matching elements:
results = rc.map do |node|
Nokogiri::CSS.xpath_for node.css_path
end
p results
Or, if you know there is only one matching element:
xpath = Nokogiri::CSS.xpath_for rc[0].css_path
Note that xpath_for returns an array, so you will need to extract the first element of the array:
xpath.first