|
I am using XmlElements and AppendChild to create an XML tree. Now, the first level from the root writes on a new line but all other XmlElements write on the same line. How do I get each new XmlElement to write on a new line with proper indentation?
My code:
XmlAttribute ApplicantAttribute = doc.CreateAttribute("UserId");
ApplicantAttribute.Value = NumberGenerator(100000, 999999, 6);
Applicant.Attributes.Append(ApplicantAttribute);
XmlNode ssnNameNode = doc.CreateElement("SSN");
ssnNameNode.AppendChild(doc.CreateTextNode(NumberGenerator(0, 999999999, 9)));
Applicant.AppendChild(ssnNameNode);
XmlNode aNameNode = doc.CreateElement("Name");
aNameNode.AppendChild(doc.CreateTextNode("Place Holdor Name"));
Applicant.AppendChild(aNameNode);
XmlNode demDataNode = doc.CreateElement("DemographicData");
demDataNode.AppendChild(doc.CreateTextNode("DemographicData"));
aNameNode.AppendChild(demDataNode);
XmlNode FullName = doc.CreateElement("FullName");
FullName.AppendChild(doc.CreateTextNode("FullName"));
demDataNode.AppendChild(FullName);
XmlNode LegalName = doc.CreateElement("LegalName");
LegalName.AppendChild(doc.CreateTextNode("LegalName"));
FullName.AppendChild(LegalName);
XmlNode Last = doc.CreateElement("Last");
Last.AppendChild(doc.CreateTextNode("Last"));
LegalName.AppendChild(Last);
XmlNode First = doc.CreateElement("First");
First.AppendChild(doc.CreateTextNode("First"));
LegalName.AppendChild(First);
Applicant.AppendChild(demDataNode);
RequestNode.AppendChild(Applicant);
The problem is that the output writes the following Xml file:
<Applicant UserId="830046">
<SSN>811163249</SSN>
<Name>Place Holdor Name</Name> <DemographicData>DemographicData<FullName>FullName<LegalName>LegalName<Last>Last</Last><First>First</First></LegalName></FullName></DemographicData>
</Applicant>
|
|
|
|
|
Doesn't matter if xml nodes are in the same line untill the xml is well formatted.
|
|
|
|
|
Bootzilla33 wrote:
I asked this question in another thread but no one answered it so I'm creating a new thread to see if someone can help. I need help with pass the value in the API to XElement in C#
Here the a piece of the API schema:
<xsd:element
name="EventStatus" type="xsd:string">
<xsd:annotation>
<xsd:documentation>Event Status</xsd:documentation>
</xsd:annotation>
</xsd:element>
Is this how that would be done?
new XElement("EventStatus", "Event Status"),
), |
|
|
|
|
|
Your question is not very clear, but I assume you want to create an XElement that when written to a file will look like this
<xsd:element name="EventStatus" type="xsd:string">
<xsd:annotation>
<xsd:documentation>Event Status</xsd:documentation>
</xsd:annotation>
</xsd:element>
This is one way to do it.
XNamespace ns = "should probably be the XSD namespace";
XElement documentation = new XElement(ns + "documentation");
documentation.SetValue("Event Status");
XElement annotation = new XElement(ns + "annotation");
annotation.Add(documentation);
XElement eventStatus = new XElement(ns + "element");
eventStatus.SetAttributeValue(XName.Get("name"), "EventStatus");
eventStatus.SetAttributeValue(XName.Get("type"), "xsd:string");
eventStatus.Add(annotation);
XElement root = new XElement("root", new XAttribute(XNamespace.Xmlns + "xsd", ns));
root.Add(eventStatus);
string s = root.ToString();
|
|
|
|
|
Hi,
I make my question after some research in web without any clear response to my problem.
I have the following XML and I need to apply an XSL transformation to get only nodes which haven't child.
Input :
<Root_Element Att_Name="XXX">
<right Id="100">
<right Id="110" />
<right Id="111">
<right Id="112" />
<right Id="113">
<right Id="114" />
<right Id="115" />
</right>
<right Id="116" />
</right>
<right Id="117">
<right Id="118" />
<right Id="119">
<right Id="120" />
<right Id="121" />
</right>
</right>
</right>
</Root_Element>
Expected output :
<Root_Element Att_Name="XXX">
<right Id="110" />
<right Id="112" />
<right Id="114" />
<right Id="115" />
<right Id="116" />
<right Id="118" />
<right Id="120" />
<right Id="121" />
</Root_Element>
|
|
|
|
|
Something like this should work:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Root_Element">
<xsl:element name="{name()}">
<xsl:apply-templates select="*|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="*">
<xsl:choose>
<xsl:when test="count(*) = 0">
<xsl:element name="{name()}">
<xsl:apply-templates select="@*"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
|
I have already gone through MSDN and multiple good known resources.
but I don't have time to elaborate and go deep in it.
I just want to give me best practices library for deeply working on xslt, XML resolver, and class library where I can implement my actual business logics using c#.Net and TPL.
|
|
|
|
|
Member 11785909 wrote: I don't have time You may find that no one here does either.
|
|
|
|
|
Apparently you were correct.
|
|
|
|
|
No surprise there.
|
|
|
|
|
I am trying to transform an XML file through code using XSL, but for some reason, the file output is displaying the entire XML as a string at the top of the document and then, just under the XML string, the document is parsed correctly by the XSL stylesheet. I would like to learn why this is happening. Here is the VB transform code:
Dim ds As New DataSet
ds.ReadXml(Server.MapPath("FormResults/" & FormID.ToString() & ".xml"))
Dim DocXSL As New XslCompiledTransform
Dim sw As New StringWriter()
ds.WriteXml(sw)
ds.Dispose()
Dim DocXML As New XmlDocument
DocXML.LoadXml(sw.ToString())
'The GetXSLContent function returns the XLS template to be used
DocXSL.Load(GetXSLContent(DFLID))
DocXSL.Transform(DocXML, Nothing, sw)
Dim result As String = sw.ToString()
sw.Close()
sw = Nothing
Me.My_Literal.Text = result.ToString()
Private Function GetXSLContent(ByVal DFLID As Integer) As String
Dim str As String = String.Empty
str = Server.MapPath("FormLetters/" & DFLID.ToString() & "_DataTemplate.xslt")
Return str
End Function
Here is the XML
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Results>
<Fields ID="48">
<Department>I.T.</Department>
<Extension>2267</Extension>
<Location>Primary Office Bldg</Location>
<Name_of_User>David</Name_of_User>
<Date>9/12/2014</Date>
<Time>04:49</Time>
<Details1>This is a test. asdf sasdf sa</Details1>
<Details2>This is only a test.</Details2>
<Details3>This is a test.</Details3>
<Details4>This is only a test.</Details4>
<Details5>This is a test.</Details5>
<Details6>This is only a test.</Details6>
<Details7>This is a test.</Details7>
<Details8>This is only a test.</Details8>
</Fields>
</Results>
Here is the XSLT
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="utf-8" omit-xml-declaration="yes"/>
<xsl:template match="/">
<div class="rndc" style="left:50%;right:50%;margin:auto;width:90%;border: 1px solid #e0e0e0;padding: 0px 5px 0px 5px">
<xsl:for-each select="Results/Fields">
<div style="text-align:left;vertical-align:top;padding: 0px 5px 0px 5px;width:96%;white-space:pre-wrap;display:inline-block">
<table style='border-collapse: collapse; left: 50%; right: 50%; margin: auto; width: 80%'>
<tr>
<td class="txtlrg" style="vertical-align:top;text-align:left" colspan="2"> <xsl:value-of select="Department"/> </td>
</tr>
<tr>
<td style="vertical-align:top;text-align:right">User Name:</td>
<td><xsl:value-of select="Name_of_User"/></td>
</tr>
<tr>
<td style="vertical-align:top;text-align:right">Extension:</td>
<td><xsl:value-of select="Extension"/></td>
</tr>
<tr>
<td style="vertical-align:top;text-align:right">Location:</td>
<td><xsl:value-of select="Location"/></td>
</tr>
<tr>
<td style="vertical-align:top;text-align:right">Date & Time:</td>
<td style="white-space:pre"><xsl:value-of select="Date"/> <xsl:value-of select="Time"/></td>
</tr>
<tr>
<td style="vertical-align:top;text-align:right">Details:</td>
<td style="white-space:pre"><xsl:value-of select="Details1"/><br />
<xsl:value-of select="Details2"/><br />
<xsl:value-of select="Details3"/><br />
<xsl:value-of select="Details4"/><br />
<xsl:value-of select="Details5"/></td>
</tr>
</table> </div>
<div style="page-break-before: always;"></div>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
Here's the output:
I.T. 2267 Gov. Center Vickie 9/12/2014 04:49 This is a test. asdf sasdf sa This is only a test. This is a test. This is only a test. This is a test. This is only a test. This is a test. This is only a test.
I.T.
User Name: David
Extension: 2267
Location: Primary Office Bldg
Date & Time: 9/12/2014 04:49
Details: This is a test. asdf sasdf sa
This is only a test.
This is a test.
This is only a test.
This is a test.
Thanks in advance!
|
|
|
|
|
TML wrote:
Dim sw As New StringWriter()
ds.WriteXml(sw)
...
DocXSL.Transform(DocXML, Nothing, sw)
Dim result As String = sw.ToString()
You've declared a single StringWriter instance. You've written the XML to it. Then you've written the results of the transformation to it.
It's hardly surprising that it then contains both the XML and the results of the transformation.
After loading the XML, you either need to create a new StringWriter instance, or you need to clear the existing one.
...
DocXML.LoadXml(sw.ToString())
sw.GetStringBuilder().Clear()
...
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
If it was a snake, it would have bit me. Thanks Richard!
|
|
|
|
|
i want to save an xml file that will look like:
"http://www.codeproject.com/script/Membership/Uploads/1234567/update.xml"
i really need help how to do this.
When i do this in google drive the link to the file do not contain .xml extension.
|
|
|
|
|
Link does not go anywhere. You need to explain your problem in proper detail.
|
|
|
|
|
iam sorry i did not explain very well.
it is not the actual link...
i mean i want to store my update.xml file somewhere on the remote location and access its link as something link www.website.com/update.xml and not as www.googledrive.com/id?=xskdhfIsksdhf
it is because i want to compare the two files update.xml in the local drives, and the www.website.com/update.xml from from remote location.
Thank you for your response.
|
|
|
|
|
Sorry I still do not understand what your problem is, or what this has to do with XML/XSL.
|
|
|
|
|
Do you have access to a domain / web site called "www.website.com"?
If you did, you would typically put "update.xml" in you website's "root directory"; or you would use some form of "redirection" to resolve the supplied address (e.g. MVC routing).
Is that clear?
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Just make a google spreadsheet, that's all.
|
|
|
|
|
I've got an XML file full of user details including 'FirstName', 'Surname' and 'StreetAddress'.
Currently my XSL file has a template (SurnameAlphabetGrouping) that groups users by the first character of the Surname element's value. I've only provided the process for 'A' to save space. All 26 letters are processed.
<xsl:template name="SurnameAlphabetGrouping">
<xsl:variable name="AMatch" select="/Users/User[starts-with(Surname, 'A')]"/>
<xsl:variable name="ACount" select="count($AMatch)"/>
<xsl:if test="$ACount > 0">
<h2>
<a href="javascript:void(0)" class="dsphead" onclick="dsp(this)">
+ A (<xsl:value-of select="$ACount"/>)
</a>
</h2>
<div class="dspcont">
<table border="1" cellpadding="1" cellspacing="1">
<tr>
<xsl:call-template name="HeadingRow"/>
</tr>
<xsl:for-each select="/Users/User[starts-with(Surname, 'A')]">
<xsl:sort select="Surname"/>
<xsl:call-template name="UserRow"/>
</xsl:for-each>
</table>
</div>
</xsl:if>
</xsl:template>
That's all well and good. But now that I've got it working that way, I really want to make it smarter (i.e. cut down the code), so I'm trying to build a template that can take the required character as a parameter.
I've got a variable (Letters) that carries tokens for the 26 letters of the alphabet:
<xsl:variable name="Letters">
<xsl:call-template name="tokenise">
<xsl:with-param name="string" select ="'A B C D E F G H I J K L M N O P Q R S T U V W X Y Z'"/>
<xsl:with-param name="delimeters" select="' '"/>
</xsl:call-template>
</xsl:variable>
I'm then attempting to process each token, passing it to the template as a parameter:
<xsl:for-each select="msxsl:node-set($Letters)/token">
<xsl:variable name="currToken" select ="./node()[1]"/>
<xsl:call-template name="ListSurnameStartsWith">
<xsl:with-param name="character" select="$currToken"/>
</xsl:call-template>
</xsl:for-each>
This is the template as it stands at the moment:
<xsl:template name="ListSurnameStartsWith">
<xsl:param name="character" select="''"/>
<xsl:variable name="charMatch" select="/Users/User[starts-with(Surname, $character)]"/>
<xsl:variable name="charCount" select="count($charMatch)"/>
<xsl:if test="$charCount > 0">
<h2>
<a href="javascript:void(0)" class="dsphead" onclick="dsp(this)">
+ <xsl:value-of select="$character"/> (<xsl:value-of select="$charCount"/>)
</a>
</h2>
<div class="dspcont">
<table border="1" cellpadding="1" cellspacing="1">
<tr>
<xsl:call-template name="HeadingRow"/>
</tr>
<xsl:for-each select="/Users/User[starts-with(Surname, $character)]">
<xsl:sort select="Surname"/>
<xsl:call-template name="UserRow"/>
</xsl:for-each>
</table>
</div>
</xsl:if>
</xsl:template>
'currToken' is getting the value I want. It's landing in the 'ListSurnameStartsWith' template just fine, but 'charMatch' just comes back blank all the time, meaning I can't get a meaningful count to test whether the output needs to be generated. The later '
|
|
|
|
|
Are you absolutely certain that the character parameter is getting the correct string value?
I've just tried the following simplified example, and it works as expected:
="1.0"
<bookstore>
<book>
<title>The Weather Pattern</title>
<author>Weather Man</author>
<price>100.00</price>
</book>
<book>
<title>Weaving Patterns</title>
<author>Weaver</author>
<price>150.00</price>
</book>
<book>
<title>Speech Pattern</title>
<author>Speaker</author>
<price>15.00</price>
</book>
<book>
<title>Writing Style</title>
<author>Writer</author>
<price>1500.00</price>
</book>
</bookstore>
="1.0"
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<root>
<xsl:apply-templates select="/bookstore">
<xsl:with-param name="character" select="'W'" />
</xsl:apply-templates>
</root>
</xsl:template>
<xsl:template match="bookstore">
<xsl:param name="character" select="''" />
<xsl:variable name="charMatch" select="book[starts-with(title, $character)]"/>
<xsl:variable name="charCount" select="count($charMatch)"/>
<result>
<char><xsl:value-of select="$character" /></char>
<count><xsl:value-of select="$charCount" /></count>
<books>
<xsl:for-each select="$charMatch">
<xsl:copy-of select="." />
</xsl:for-each>
</books>
</result>
</xsl:template>
</xsl:stylesheet>
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Richard,
Thanks for your reply.
Yes, if I pass 'A' to the template, I get the correct answer. So that's a good thing.
Now, given a tokenised string stored in a variable (Letters):
<xsl:variable name="Letters">
<xsl:call-template name="tokenise">
<xsl:with-param name="string" select ="'A B C D E F G H I J K L M N O P Q R S T U V W X Y Z'"/>
<xsl:with-param name="delimeters" select="' '"/>
</xsl:call-template>
</xsl:variable>
And trying to process each token through the template:
<xsl:for-each select="msxsl:node-set($Letters)/token">
<xsl:variable name="currToken">
<xsl:value-of select="./node()[1]"/>
</xsl:variable>
<xsl:call-template name="ListSurnameStartsWith">
<xsl:with-param name="character" select="$currToken"/>
</xsl:call-template>
</xsl:for-each>
What should I be using inside the 'select' attribute to ensure that i get 'A' and not some other value.
Some options I've tried, debugging in Visual Studio 2013, are:
<xsl:variable name="currToken">
<xsl:value-of select="."/>
</xsl:variable>
This gives me:
$currToken {Dimension:[1]}
[1] /
node()[1] A
'select="./node()"' gives me the same answer.
'select="./node()[1]"' gives me the same answer.
I haven't had any help from Google, as I can't seem to ask the right question, or nobody's doing this.
What do I need to put into the select to actually get the character A.
|
|
|
|
|
Have you tried:
./text()[1]
If that doesn't work, can you post your "tokenise" template?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Richard,
Sorry I haven't replied earlier. I went on leave the day you responded and have been... occupied since.
I tried your suggestion, without success, although it has given me something to pursue.
As requested, the tokenisation templates I gleaned from other forum sources a fair while ago are below. It worked well for what I was doing then, but it may not be the best for what I'm attempting now.
Any advice would be appreciated.
<xsl:template name="tokenise">
<xsl:param name="string" select="''" />
<xsl:param name="delimiters" select="' '" />
<xsl:choose>
<xsl:when test="not($string)" />
<xsl:when test="not($delimiters)">
<xsl:call-template name="_tokenise-characters">
<xsl:with-param name="string" select="$string" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="_tokenise-delimiters">
<xsl:with-param name="string" select="$string" />
<xsl:with-param name="delimiters" select="$delimiters" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="_tokenise-characters">
<xsl:param name="string" />
<xsl:if test="$string">
<token>
<xsl:value-of select="substring($string, 1, 1)" />
</token>
<xsl:call-template name="_tokenise-characters">
<xsl:with-param name="string" select="substring($string, 2)" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="_tokenise-delimiters">
<xsl:param name="string" />
<xsl:param name="delimiters" />
<xsl:param name="last-delimit"/>
<xsl:variable name="delimiter" select="substring($delimiters, 1, 1)" />
<xsl:choose>
<xsl:when test="not($delimiter)">
<token>
<xsl:value-of select="$string"/>
</token>
</xsl:when>
<xsl:when test="contains($string, $delimiter)">
<xsl:if test="not(starts-with($string, $delimiter))">
<xsl:call-template name="_tokenise-delimiters">
<xsl:with-param name="string"
select="substring-before($string, $delimiter)" />
<xsl:with-param name="delimiters"
select="substring($delimiters, 2)" />
</xsl:call-template>
</xsl:if>
<xsl:call-template name="_tokenise-delimiters">
<xsl:with-param name="string"
select="substring-after($string, $delimiter)" />
<xsl:with-param name="delimiters" select="$delimiters" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="_tokenise-delimiters">
<xsl:with-param name="string"
select="$string" />
<xsl:with-param name="delimiters"
select="substring($delimiters, 2)" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
|
|
|
|