Extracting a value from XML and storing it in a variable - css

here is my sample XML :
<Entries>
<Entry>
<id>1</id>
.
.
</Entry>
<Entry>
<id>2</id>
<assets>
<TextAssetInfo>
<Name>Alpha</Name>
<TagName>alphaName</TagName>
<value>Harambe</value>
</TextAssetInfo>
</assets>
</Entry>
<Entries>
So my goal is simply to extract the value of Alpha and store it in a variable in my XSLT for further computation.
I am able extract and print the value. But not assign in to a variable.
Following part of XSL code works:
<T_AlphaName><xsl:value-of select="./assets/*[TagName = 'alphaName']/value"/></T_AlphaName>
However, I can't get the below to work :
<xsl:variable name="myVar" select="./assets/*[TagName = 'alphaName']/value"/>
I have tried many other combinations as well but no luck. What am I doing wrong? In my XSL I have part to test it and get a weird result
<TestVar><xsl:value-of select="$myVar"/></TestVar>
Result : <TestVar/>
Additional info :
Using XML/XSL version 1.0.
AlphaName is not the only TextAssetInfo inside the assets. There are many more.

Related

How to delete many occurrences of a symbol within comments in an XML file in R, delete the symbol and save it back to XML with the original name?

I need to delete several occurrences of a symbol (single quote) within comments in an XML file in R, and then save it back to XML. I have to do this in 1000s of XML file.
In each XML file the single quote appears more than 50 times and present in different child hierrachial structure (some in child and some in sub-child). But always present within the comments.
I Tried using XML package in R. I first tried to enable this one XML file, but didn't know how to proceed further.
library(XML);library(xml2);library(methods);library(tidyverse)
#Read one XML file
filepath <- "C:/Users/PeriaPr/Desktop/repex1.xml"
onefile <- xmlTreeParse(gsub("'","",readLines(filepath)),asText = TRUE)
xmlroot <- xmlRoot(onefile)
var <- xmlSApply(xmlroot, function(x) xmlSApply(x, xmlValue))
Here is a reproducible example of my XML file. The single quotes (around Orange, Apple and Banana) need to be removed in this multiple tree hierarchical structure. The quotes occur almost 50 times within one XML file, and I need to process (delete single quotes) 1000s of XML files
<?xml version = "1.0" encoding = "windows-1252"?><document id="myrepex.xml">
<action_step step_no="1.3.1.1">
<step>1</step>
<title><![CDATA[Part1 - 'Apple']]></title>
<start><![CDATA[2019/08/09 7:57:17]]></start>
<duration><![CDATA[0 Hr. 12 Min. 22 Sec.]]></duration>
<status><![CDATA[Passed]]></status>
</action_step>
<action_step step_no="1.4.1.1">
<step>2</step>
<title><![CDATA[Part2 - 'Orange']]></title>
<start><![CDATA[2019/08/09 8:09:39]]></start>
<duration><![CDATA[0 Hr. 32 Min. 55 Sec.]]></duration>
<status><![CDATA[Passed]]></status>
</action_step>
<action_step step_no="1.5.1.1">
<step>68</step>
<title><![CDATA[Part3 - 'Banana']]></title>
<start><![CDATA[2019/08/09 8:42:35]]></start>
<duration><![CDATA[0 Hr. 36 Min. 28 Sec.]]></duration>
<status><![CDATA[Passed]]></status>
</action_step>
<action_step2 secondchild="secondchild">
<action_step2subchild subchild="subchild">
<title><![CDATA[Part3 - 'Banana']]></title>
</action_step2subchild>
</action_step2>
To delete all single quotes in the content of title elements, you can use the following XSLT 3.0 stylesheet:
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="title/text()">{translate(.,"'","")}</xsl:template>
</xsl:transform>
If you want to retain the CDATA tagging (which is considered by XSLT to be pure noise), add an xsl:output declaration with cdata-section-elements attribute.
To apply this transformation to many source XML files, you could either (a) use Saxon's ability to process all files in a directory from the command line, (b) put the control logic within the XSLT stylesheet (using the collection() function), or (c) use some external control logic, e.g. XProc, Ant, or a shell script.
Consider this XSLT 1.0 script and then iterate with R's xslt package (extension of xml2):
XSLT (save as .xsl file to be read in R)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"
cdata-section-elements="title start duration status"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="single_quote">&apos;</xsl:variable>
<xsl:template match="title">
<xsl:copy>
<xsl:value-of select="translate(., $single_quote, '')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Online Demo
R
library(xml2)
library(xslt)
# RETRIEVE ALL XML FILES
setwd("C:/path/to/xml/files")
xmls <- list.files(pattern="xml")
# LOAD XSLT
style <- read_xml('C:/path/to/Script.xsl', package = "xslt")
# USER-DEFINED METHOD
proc_xml <- function(xml_file) {
# LOAD XML AND XSLT
doc <- read_xml(xml_file)
# TRANSFORM XML
new_xml <- xslt::xml_xslt(doc, style)
# SAVE NEW XML (REMOVE paste0 TO OVERWRITE ORIGINAL XML)
write_xml(new_xml, paste0("new_", xml_file))
return(new_xml)
}
# ITERATE THROUGH XML FILES
new_xmls <- lapply(xmls, proc_xml)

How to dynamically fetch value using cts:seach in Marklogic?

My Database is having "n" number of documents and i need to search for document dynamically using the elements and value i am providing. I am explaining it below-
Sample documents in my database-
document1-
<root>
<id1>12345</id1>
<value>Country</value>
<node1>somevalue</node1>
<node2>somevalue</node2>
<node3>somevalue</node3>
<node4>somevalue</node4>
.......................
</root>
document2-
<root>
<id2>34567</id2>
<value>Fruits</value>
<node1>somevalue</node1>
<node2>somevalue</node2>
<node3>somevalue</node3>
<node4>somevalue</node4>
.......................
</root>
I need to give input parameters as Rest End Point to perform my operation and the input to rest xml document is as below-
INPUT XML-
<root>
<id>id1</id>
<idvalue>12345</idvalue>
.......................
</root>
Output i need is shown in example-
Example- Search for all the documents from the database which is having Id=Id1 and it's value=12345
Any Suggestions ?
You can explore Query By Example (QBE) of MarkLogic. For more details go to URL https://docs.marklogic.com/guide/search-dev/qbe
XPath can extract the input values for constructing a cts.elementValueQuery().
Something similar to the following should work in SJS:
cts.search(cts.elementValueQuery(
xs.QName(fn.string(input.xpath('/root/id'))),
fn.string(input.xpath('/root/idvalue'))
))
Or similar to the following in XQuery:
cts:search(fn:collection(), cts:element-value-query(
xs:QName(fn:string($input/root/id)),
fn:string($input/root/idvalue)
))
For more information, see http://docs.marklogic.com/cts.elementValueQuery
Hoping that helps,

Entity replacement not working in a KML/XML file, how do I use this data?

basically I want to put information into a balloon in Maps API, this is the KML file, the data is stored using SimpleData tags, and I am trying to access to it from the BalloonStyle text tag.
But it doesn't work, in the baloon is displayed simply $[something]. After some research, I discovered Entity replacement may not be supported anymore by SimpleData tags.
So how do I manage the data? I got the data from ogr2ogr conversion from a shapefile and I don't know how to manage its output to make it use ExtendedData and Data tags.
Thank for your help.
You can replace <SchemaData><SimpleData> with <Data><value> elements with a text editor preferably one that can perform regular expression replacements on searches such as NotePad++.
You start with this:
<ExtendedData>
<SchemaData schemaUrl="#biblioteche">
<SimpleData name="INDIRIZZO">VIA SAN VITTORE, 21</SimpleData>
<SimpleData name="TIPOLOGIA">BIBLIOTECHE</SimpleData>
...
<SimpleData name="ID">0</SimpleData>
</SchemaData>
</ExtendedData>
And need to convert to this form:
<ExtendedData>
<Data name="INDIRIZZO">
<value>VIA SAN VITTORE, 21</value>
</Data>
<Data name="TIPOLOGIA">
<value>BIBLIOTECHE</value>
</Data>
...
<Data name="ID">
<value>0</value>
</Data>
</ExtendedData>
Globally make the following replacements (in this order):
#
Find what
Replace with
1.
<SchemaData schemaUrl="#biblioteche">
2.
</SchemaData>
3.
<SimpleData
<Data
4.
(<Data name=".*?">)
\1<value>
5.
</SimpleData>
</value></Data>
Steps 1 and 2 have an empty target such that you delete the element.
Step 4 is the only step that needs to be done as a regular expression.
working example

What is cstyle in XSLT?

My XSLT is shown below.
aic is a namespace.
What is cstyle?
is it a built-in XSLT element/function?
Or an element within the expected input xml?
<xsl:stylesheet exclude-result-prefixes="aic"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:aic="http://ns.adobe.com/AdobeInCopy/2.0/" >
<xsl:template match="/">
</xsl:template>
<xsl:template match="aic:cstyle[contains(#name,'bold')]">
</xsl:template>
</xsl:stylesheet>
It is an element within the expected input XML. The XPaths in an XSLT's match attributes are generally applied to contents from the input XML.
Exactly as in my answer to your previous question, aic:cstyle is a selector that matches elements whose local name is cstyle and whose namespace URI is http://ns.adobe.com/AdobeInCopy/2.0/ (the URI bound to the aic prefix in the xsl:stylesheet element). Thus
<xsl:template match="aic:cstyle[contains(#name,'bold')]">
is a template that will apply to any {http://ns.adobe.com/AdobeInCopy/2.0/}cstyle element that has a name attribute that contains the substring bold. (So, to answer your question directly: the expression in question will match elements in the input streams for which the stylesheet was written.)
As with any new programming language, I would strongly recommend that you find a decent tutorial and work through that to get comfortable with the syntax and idioms of the language through simple examples before you start trying to decode a large and complex XSLT that you've inherited from elsewhere.

Is it possible to use a variables inside xsl:key instruction?

Relating to this question, is it possible to use variables inside xsl:key? I want to do smth like this:
<xsl:key name="ChargesKey" match="$ChargesForDisplay/charge" use="Name"/>
I'm using XSLT 1.0 with ASP.Net
I believe I can safely assume that you are referring to dynamically-generated node-set variables (as opposed to those selected from the source DOM, which are trivial), and yes it is possible to perform a key-match on the contents of a dynamically generated node-set variable (as I demonstrate for this question).
Assuming you have a variable like this:
<xsl:variable name="ChargesForDisplay">
<charge>
<Name>Name1</Name>
</charge>
<charge>
<Name>Name2</Name>
</charge>
<charge>
<Name>Name1</Name>
</charge>
<charge>
<Name>Name3</Name>
</charge>
</xsl:variable>
You would define the key like this:
<xsl:key name="ChargesKey" match="charge" use="Name"/>
And then you can apply it like this:
<xsl:template match="/">
<xsl:apply-templates select="msxsl:node-set($ChargesForDisplay)" />
</xsl:template>
<xsl:template
match="charge[generate-id(.)=generate-id(key('ChargesKey',Name)[1])]">
<xsl:variable name="matchingItems" select="key('ChargesKey', Name)" />
...
</xsl:template>
Of course, if the variable contains a selection of nodes from the source XML DOM, then it's just the same approach, except you don't need to use msxsl:node-set().
I suspect that having a key on a node-name that's also present in the source XML document or multiple dynamically-generated node-set variables may cause grouping to produce unexpected results(because the key() function would locate nodes from both the variable and the source document). For this reason, I'd suggest defining keys on nodes that would only be present in one particular variable and nowhere else.
The match attribute of xsl:key must be a valid pattern and $x/y is not a valid pattern. So, the answer is no. Now tell us what you are trying to achieve and we can help you achieve it. (JLRishe makes some wild guesses, which s/he calls "wild assumptions", and which may well be right; but I don't know where the guesses come from).

Resources