xpath for matching DateTime format - c#

Im writing an xslt to find all elements with specific Date formats. But the "match" statement seems to be a problem. I need to format this date to a custom format using C# code. Any help would be great..
my XSLT is:
<xsl:template match="text()[.='[M01]/[D01]/[Y0001]']">
<xsl:value-of select="userCSharp:GetFormatedDate(.)" />
</xsl:template>
My Xml is:
<Root>
<Name>Don</Name>
<EffectiveDate>01/30/2015</EffectiveDate>
</Root>

I presume you are using XSLT 1.0? If so, try:
<xsl:template match="text()[translate(., '123456789', '000000000') = '00/00/0000']">
<xsl:value-of select="userCSharp:GetFormatedDate(.)" />
</xsl:template>
Note that this matches any text node having a pattern of ##/##/####. It does not check for a valid date in MM/DD/YYYY format. A "date" of 99/99/9999 would pass this test too.

Related

c# How to get attribute name from xslt

I have following part of xslt in string format :-
<xsl:if test="TestValue3 and TestValue3 != ''">
<xsl:attribute name = "TestDate" >
<xsl:value-of select = "TestValue3" />
</xsl:attribute>
</xsl:if>
I just want to fetch its attribute name from c# code.
Attribuute Name= TestDate
How can I achieve this?
Use your favourite XML API to load the XSLT and iterate/query the item in question (in this case you would need to look for the owning xsl:if and the condition itself). e.g. you could load it into an XmlDocument or XDocument.
You can use XPath to find the element for XmlDocuments or if you use XDocument you can use LINQ.
Do not attempt to use technologies that are not equipped for structured data.
i.e.
don't use flat string search
don't use regex
Actually I am adding above block into existing xslt ,, but before adding I need to check if attribute name =TestDate already exists ... For that I need to know attribute name , becase attribute name can vary as per block,, it is not fix each time
Again, use the above recommendations. Both XmlDocument and XDocument allow for load/edit/save.
If I understand you correctly this should do the job, otherwise please add more context.
<xsl:if test="TestValue3 and TestValue3 != ''">
<xsl:if test="not(#TestDate)">
<xsl:attribute name = "TestDate" >
<xsl:value-of select = "TestValue3" />
</xsl:attribute>
</xsl:if>
</xsl:if>

How to select an attribute value in an XML and concatenate it with a string and use it as an attribute value in a new XML using XSLT

I need to transform an existing XML into another XML using XSLT.
The problem I am facing is that I need to use the "typeName" attribute from the ECClass and concatenate it with http://www.semanticweb.org/aman.prasad/ontologies/2015/5/untitled-ontology-1#
The XML i am working with is -
<ECSchema>
<ECClass typeName="ABC">
<BaseClass>PQR</BaseClass>
<BaseClass>XYZ</BaseClass>
</ECClass>
<ECClass typeName="IJK">
<BaseClass>MNO</BaseClass>
<BaseClass>DEF</BaseClass>
</ECClass>
<ECSchema>
For example the concatenated result should be -
http://www.semanticweb.org/aman.prasad/ontologies/2015/5/untitled-ontology-1#ABC for the first ECClass
I need to set this string as the attribute value of rdf:about in the owl:class tag in the new XML structure.
The new XML structure is -
<owl:ontology rdf:about="http://www.semanticweb.org/aman.prasad/ontologies/2015/5/untitled-ontology-1">
<owl:class rdf:about="http://www.semanticweb.org/aman.prasad/ontologies/2015/5/untitled-ontology-1#ABC">
</owl:class>
<owl:class rdf:about="http://www.semanticweb.org/aman.prasad/ontologies/2015/5/untitled-ontology-1#ABC">
</owl:class>
</owl:ontology>
Right now I have not yet tried to do anything about the BaseClass. I have only been trying to convert the ECCLass to owl:class.
The XSL for it is -
<xsl:template match="/">
<owl:Ontology rdf:about="http://www.semanticweb.org/aman.prasad/ontologies/2015/5/untitled-ontology-1"/>
<xsl:for-each select="ECSchema/ECClass">
<owl:class rdf:about="<xsl:value-of select="concat('http://www.semanticweb.org/aman.prasad/ontologies/2015/5/untitled-ontology-1#' , '#typeName') />" >
</owl:class>
</xsl:for-each>
</xsl:template>
I have been trying many combinations to do this from various sources but haven't been able to do it.
It always returns an error - "Additional information: '<', hexadecimal value 0x3C, is an invalid attribute character."
Can anybody please help me with this as I am very new to XSLT and all I have been getting is lots of errors.
Tags cannot be nested. To achieve your purpose, you should learn about attribute value templates. In addition, your code is rather sloppy. Try it this way:
<xsl:template match="/">
<owl:Ontology rdf:about="http://www.semanticweb.org/aman.prasad/ontologies/2015/5/untitled-ontology-1">
<xsl:for-each select="ECSchema/ECClass">
<owl:class rdf:about="{concat('http://www.semanticweb.org/aman.prasad/ontologies/2015/5/untitled-ontology-1#', #typeName)}" />
</xsl:for-each>
</owl:Ontology>
</xsl:template>
or perhaps a bit more elegant:
<xsl:variable name="myURL">http://www.semanticweb.org/aman.prasad/ontologies/2015/5/untitled-ontology-1</xsl:variable>
<xsl:template match="/">
<owl:Ontology rdf:about="{$myURL}">
<xsl:for-each select="ECSchema/ECClass">
<owl:class rdf:about="{$myURL}#{#typeName}" />
</xsl:for-each>
</owl:Ontology>
</xsl:template>

XPath problems in C# XSLT transformation

I am trying to parse an XML document to a website, through a XSLT transformation.
However, to make it work I have to use the following XPath:
/*[name()='standards']/*[name() = 'standard']
Why does the following XPath expression not work?
/standards/standard
Your problem is the most FAQ in XPath -- search for XPath and default namespace and you'll find many good answers.
To summarize the problem: XPath interpretes any unprefixed name as belonging to "no namespace".
Therefore any unprefixed name in any XPath expression, belonging to some default namespace (not the "no namespace") isn't selected.
One way to continue to use names in the location steps is to indicate to the XPath processor that a specific prefix, say "x" is associated to the default namespace. Then issue:
/x:standards/x:standard
In .NET such namespace binding (called "registering of namespace") is done using the XmlNamespaceManager class. See this complete example.
In XSLT, simply define a namespace at a global level, then specify XPath expressions where each element name is prefixed by the prefix so defined.
Here is a small example:
<nums xmlns="some:nums">
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
To process the above XML document we have this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="some:nums">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:value-of select="/x:nums/x:num[. = 3]"/>
</xsl:template>
</xsl:stylesheet>
Applying this transformation to the above XML document correctly selects the wanted element and outputs its string value:
03
I don't know what your question is. Just taking a wild stab, perhaps this is what you want ...
<xsl:stylesheet version="1.0"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ikas="http://www.ikas.dk"
exclude-result-prefixes="msxsl ikas">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<div xmlns="http://www.ikas.dk">
<textarea>
<xsl:copy-of select="/ikas:standards/ikas:standard"/>
</textarea>
</div>
</xsl:template>
</xsl:stylesheet>

Can XPathSelectElement ignore case?

Is there a way to ignore case when we try to use XPathSelectElement or any operation like to retrieving attributes from XDocument? The purpose for asking this question is that, I have some configuration files (xml) and I am writing a generic code that will read the config files to get required information for XPathSelectElement. Also, I try to get the values of attributes. Even if someone puts the nodes/attributes in different case, my program should be able to work without fail.
I use C#/.Net 3.5.
You can't ignore case with XPath. You can accomodate, though.
For example - elements, assuming they contain letters in the ASCII range only:
//*[
translate(
name(),
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'
) = 'myname'
]
Attributes would work the same (with #* in place of *).
If you do not want to bloat your XPath expressions with this, you could lower-case all element- and attribute names beforehand, for example via XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node() | #*" />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{translate(name(), $upper, $lower)}">
<xsl:apply-templates select="node() | #*" />
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:attribute name="{translate(name(), $upper, $lower)}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Before you load the XML string make lower-case. That will solve the issue. I use this method myself.

xsl format date (substring + concatenate ?)

I have the input
<Date value="20091223"/>
and I want the output to be
<Date>23122009</Date>
I was trying to use substring function to reformat the date
<xsl:value-of select="substring($Date,1,4)"/>
But how to concatenate the extracted year and months and day together.
Assuming whitespace isn't preserved, just put them one after the other:
<xsl:value-of select="substring($Date,7,2)"/>
<xsl:value-of select="substring($Date,5,2)"/>
<xsl:value-of select="substring($Date,1,4)"/>
If whitespace is preserved, just put them all on the line, without spaces between them.
The Xpath concatenation function will also work, but I find it less readable:
<xsl:value-of select="concat(substring($Date,7,2), substring($Date,5,2), substring($Date,1,4))"/>
<xsl:value-of select="substring(Date/#value, 7, 2)"/>
<xsl:value-of select="substring(Date/#value, 5, 2)"/>
<xsl:value-of select="substring(Date/#value, 1, 4)"/>
Take a look at the XSLT concat function. In your case it would be something like this (untested):
<xsl:value-of select="concat(substring($Date,1,4), substring($Date,7,2), substring($Date,5,2))"/>
Try this
<xsl:value-of select="concat(substring($Date,7,2),substring($Date,5,2),substring($Date,1,4))"/>

Categories

Resources