This might be ridiculous, but I have a C# function that returns a string to JavaScript via AJAX. The first part of the string is HTML, and the second part is XML. The string will look something like:
"""
<b>Some HTML</b> - this entire string is returned from the server.
<i>I have no control over it</i>.
<br/>
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
</catalog>
</xml>
"""
Then I have a function that creates a jQuery UI modal dialogue that contains this string as the main text. It correctly renders the first part as HTML, but the second part (the XML) is invisible
What I need is to render the HTML as it is now, but also render out the XML as a plaintext string (as you see in the example above). Ideally, I would like a server-side solution, but I am guessing it has to be client-side.
I would use something like new XMLSerializer()).serializeToString(combinedString) but won't that also get rid of the HTML tags?
Note: I do not know the HTML text ahead of time. I don't know if it will be seperated by newlines, <p> tags, <div>'s, or whatever else, so I can't exactly do something like String.Split('\n').
You should HTML encode the XML portion in the server side before returning the result to the client. Use HttpUtility.HtmlEncode function to complete this task.
For further details:
https://msdn.microsoft.com/en-us/library/system.web.httputility.htmlencode(v=vs.110).aspx
Related
Can an HTML form be bound to an XML document?
To give some context, Adobe XFA forms are XML documents created for purpose of rendering as a PDF form. They support XML bindings very similar to what I am looking for, but I'm not aware of anything similar in HTML forms and seeking suggestions.
An XFA form can also define bindings to an XML document that are bound to its form fields. It is not necessary for a schema to be defined -
the form can be merged with XML data or it can generate XML data based on the bindings specified in the form.
Example form definition:
<subform layout="tb">
<bind match="dataRef" ref="$.doc" />
<field w="0.5in">
<bind match="none" />
<ui>
<button />
</ui>
<caption>
<value>Add</value>
</caption>
<event activity="click" name="event__click">
<script contentType="application/x-javascript">
this.resolveNode("itemList").instanceManager.addInstance();
</script>
<event>
</field>
<subform layout="tb" name="itemList">
<bind match="dataRef" ref="$.item[*]">
<occur min="1" max="-1" />
<field w="2in">
<bind match="dataRef" ref="$.name" />
<ui>
<textEdit />
</ui>
<caption>
<value>Name</value>
</caption>
</field>
</subform>
</subform>
If the form was rendered with no data, it would appear similar to:
If the form was merged with the following input data:
<doc>
<item>
<name>item1</name>
</item>
<item>
<name>item2</name>
</item>
<item>
<name>item3</name>
</item>
</doc>
It would render similar to:
As you may notice in the form defintion code, Adobe XFA form is using its own XML language and expression syntax called SOM expressions. The first binding $.doc is binding to the top-level root node name doc.
The next binding $.item[*] is nested with the subform element and is relative to the $.doc binding.
The subform element is a container, similar to an HTML div element.
The subform is bound to item elements under the root doc element. the [*] syntax means that the subform will repeat itself for each item element in the xml document.
The occur element within the the subform element further qualifies how many instances can occur. The min=1 means that even if there are no item elements in the data merged into the form, it will automatically generate one. The max=-1 means there is no limit on the number of item instances.
The field element is bound to $.name. This means its value will update (or create) a name element under the current item.
The 'Add' button in the form creates new instances, Adobe Reader has a built-in Javascript engine and its own API to manage instances of the form that are persisted back to the XML data bound to the form.
Of course, the XML data can also be extracted from a saved PDF form.
There are many more capabilities in XFA forms such as conditional bindings, but I'm curious if something along these lines exists in HTML forms, perhaps some library that can link a form to an XML document and target them in a similar way.
XPATH would be ideal instead of the Adobe SOM expression syntax. Also, it would be ideal to have the XML posted from the form rather than name / value pairs that HTML forms would do by default.
There are many ways to convert XML into an HTML form. This question sounds an awful lot like a tool recommendation, so the only thing to do is list options:
Method 1:
This site walks the user through pasting an XML document, and then turns it into a form. It's pretty outdated, since the last change log was in 2006.
http://www.datamech.com/XMLForm/
Method 2:
You can write the script yourself, by converting XML > JSON then JSON > HTMLForm.
Converting the XML into JSON tools:
xml-js (NPM module)
xml2json (more popular, but has issues installing in Windows)
Blog tutorial (hand-made code)
Converting JSON into form tools:
json-forms (This might need you to follow a specific schema.)
Write the code yourself!
I'm guessing that what you're looking for is XSLT. This lets you transform a well-formed document of one kind into another. If this is what you want, there's a good answer here already.
In case other people stumble across this same question, you can get to exactly what you are looking for (creating html from xml documents) using xslt.
Think of this lonely post as your jumping off point to xslt. If you've never dealt with it before, it can be a little hard to digest. Fear not. Every journey begins with the first step. (etc. etc.)
Start with xml, and some idea of the html you want to create
So - for your example XML:
<doc>
<item name="Item1" />
<item name="Item2" />
<item name="Item3" />
</doc>
Let's assume you want to create a fairly simple HTML snippit:
<form class="tb">
<div><a class="btn btn-primary">Add</a></div>
<ul>
<li><label>Name</label><input type="text" class="form-control" value="Item1" /></li>
<li><label>Name</label><input type="text" class="form-control" value="Item2" /></li>
<li><label>Name</label><input type="text" class="form-control" value="Item3" /></li>
</ul>
</form>
Next, build your Xslt
There's some work at the beginning, and some syntax to learn. But, if we cut to the chase, this is the xslt that you'll end up with. It's just text. Just another file that you can hard code, embed, store in a file, grab from a url, etc.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="html" />
<xsl:template match="doc">
<form class="tb">
<div><a class="btn btn-primary">Add</a></div>
<ul>
<xsl:for-each select="item">
<li><label>Name</label><input type="text" class="form-control" value="<xsl:value-of select="#name"/>" /></li>
</xsl:for-each>
<xsl:if test="count(item)=0">
<li><label>Name</label><input type="text" class="form-control" value="" /></li>
</xsl:if>
</ul>
</form>
</xsl:template>
A few Xslt Notes
As you can see from the above, you setup a BASE document node to loop through with the <xsl:template match="doc"> tag. If your xml document has a doc node, then the html within the template is included. If there isn't a doc node, then it's skipped.
You can break out your xslt into different templates - and include them in the main template as well. It's pretty cool.
In the example above, we loop through your item nodes with an <xsl:for-each> tag, and we even have an "alternate" html which gets displayed if there are ZERO item tags (that's the empty input tag surrounded by
<xsl:if test="count(item)=0">).
There are some really great xslt references out there, but I like the one from Microsoft because I can use the c# code below to get html from a specific xslt tempate and my xml doc.
Finally, put it all together
Once you have your xml (above) and your xslt (also above), you can use them both to generate a string of html that is as long and complicated as you'd like. This is an almost verbatim copy of the method we use to generate massive mortgage contracts from xslt and really complex xml documents. I swear - it's lightning quick, and produces thousands of pages of html every day for us.
private string GetHtmlFromXslt(string xml, string xslt) {
XslCompiledTransform transform = new XslCompiledTransform();
using (XmlReader reader = XmlReader.Create(new StringReader(xslt))) {
transform.Load(reader);
}
StringWriter results = new StringWriter();
using (XmlReader reader = XmlReader.Create(new StringReader(xml))) {
transform.Transform(reader, null, results);
}
return results.ToString();
}
This is a .net core project file, referencing just System.Xml and System.Xml.Xsl - both of which are standard in System.Xml.
C-sharp!? Blech! Ach! The OP said JAVASCRIPT. Jeez...
I know you are a javascript guy. There are tools to do exactly the same thing (exactly) here and here.
I just haven't used those libraries because all of our xml is (a) private and (b) located on servers. But - I took a look at the code and they both follow the same approach -- one xml file and one xslt file, married with about 8-10 lines of actual code and producing a lovely html baby.
So. That's it. No tools. No third party plugins. No crazy json stuff.
Good luck! Can't wait to see what you crazy-kids create!
I want to encode the html tags as a string except some tags like anchor tag using javascript
something similar to php's function "htmlspecialchar"
Note: I never wants to stripe the html tags.
Suppose my html string is like
<div><span>test string</span>div content goes here <a herf="xyz.com">My Portal</a></div>
Expected output should be
<div><span>test string</span>div content goes here My Portal </div>
Here "My portal should" turns to hyperlink instead of getting encoded. but rest all other tags are get encoded and should be displayed on view as string
I am taking inputs from user, then adding links for mentioned users and then passing the same in the template
Input: hello #ds
String after adding links -
"#<a class="tweet-url username" href="/user/ds" data-screen-name="ds" rel="nofollow">ds</a>"
Passing the above string in .Msg (using golang template) :
<div class="panel-body" >
<p > {{.Msg}} </p>
</div>
Expected outcome is: Hello #ds (with clickable link on #ds)
However getting everything in text format (same as input).
#<a class="tweet-url username" href="/user/ds" data-screen-name="ds" rel="nofollow">ds</a>
What am I missing?
Got a better solution. First of all I am doing htmlEscape on the input then store it in db, then while presenting adding links followed by using document.write(string) function. With this I dont have to change the template and I dont have to worry about XSS attach. Also I am also avoiding XSS scripts in my database. –
Try wrapping your string (Msg) in template.HTML to disable the escaping that html/template does.
Example from the docs:
The template
Hello, {{.}}!
can be invoked with
tmpl.Execute(out, template.HTML(`<b>World</b>`))
to produce
Hello, <b>World</b>!
instead of the
Hello, <b>World<b>!
that would have been produced if {{.}}
was a regular string.
Note that you should do this with great care... make sure that you trust the string you're wrapping in template.HTML. This is an easy way to open yourself up to XSS attacks.
all:
I want to send creating calendar item operation request using EWS, and some of my content, for instance, Subject, may content Chinese characters. Here is what my request soap looks like
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Header>
<RequestServerVersion xmlns="http://schemas.microsoft.com/exchange/services/2006/types" Version="Exchange2007_SP1"/>
</Header>
<Body>
<CreateItem xmlns="http://schemas.microsoft.com/exchange/services/2006/messages" SendMeetingInvitations="SendToNone">
<SavedItemFolderId>
<DistinguishedFolderId xmlns="http://schemas.microsoft.com/exchange/services/2006/types" Id="calendar"/>
</SavedItemFolderId>
<Items>
<CalendarItem xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
<Subject>新建日程</Subject>
<ReminderIsSet>true</ReminderIsSet>
<ReminderMinutesBeforeStart>15</ReminderMinutesBeforeStart>
<Start>2016-06-22T09:00:00</Start>
<End>2016-06-22T10:00:00</End>
</CalendarItem>
</Items>
</CreateItem>
</Body>
</Envelope>
I encode this xml with utf-8 and send it to my testing exchange server, and after a while, it displayed on that server, but with question mark in Subject property instead of '新建日程'. All other properties are displayed correctly.
So I wonder where I did wrong that the Chinese content can not be displayed correctly. Any suggestions?
Finally, I figure out what's wrong. It's in the request header. I found that the header forgot to set charset as utf-8. What a simple but stupid mistake.....
This is a really confusing error, as it crops up in some of the webpages that I'm creating, but not in others, although syntactically the elements are identical.
For example, this doesn't show up:
<main:uiInputBox
onDarkBG="${hasDarkBG}"
name="questionTitle1"
onblur="pollUpdateQuestion(false, false, true, this);"
defaultValue="<${field['POLL_FIELD_ENTER_QUESTION']}>"
styleWidth="280px">
</main:uiInputBox>
Where the tag ${field['POLL_FIELD_ENTER_QUESTION']} should return the string "enter question". What I don't understand is that the tag returns the string normally in the JSP file, but now when it's in the HTML descriptor.
Another error is that in javascript if I have a function like this:
It prints out the literal string "${field['POLL_FIELD_CHOICE']}", and not the element that it's representing. Ex:
template.find('h2').text('${field["POLL_FIELD_CHOICE"]} ');
What am I doing wrong here and how can I fix it?
As to the first problem of EL not being resolved in a custom tag, that's not JSTL (it are those <c:xxx> tags). That's EL (those ${} things).
You seem to be using EL in a custom tag. The <main:xxx> does not belong to any JSP standard tag library (look, that's what JSTL stands for). To get EL in custom tags to work as well, you need to ensure of the following:
The web.xml must be declared as at least Servlet 2.4, which implies JSP 2.0 where this feature is supported.
<web-app
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
The .tld file of the <main:xxx> taglib must be declared as at least JSP 2.0, where the <rtexprvalue> attribute is supported.
<taglib
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
The defaultValue attribute in the .tld file of the <main:uiInputBox> must be marked with <rtexprvalue>true</rtexprvalue> to enable the support runtime expressions (the EL, those ${} things).
<attribute>
<name>defaultValue</name>
<rtexprvalue>true</rtexprvalue>
</attribute>
As to the second problem of EL not being resolved in a JavaScript file, well, the explanation is pretty simple: EL in template text like that runs in JSP (2.0 or newer) files with .jsp extension only. There are several ways to get it to work anyway:
Rename .js to .jsp and add the following line to top of the page (best solution):
<%#page contentType="text/javascript" %>
Put that piece of JS in an inline <script> of the JSP page instead (not recommend since that's generally seen as a poor practice).
Map *.js on the JSP servlet in web.xml (not recommended, it tight-couples your webapp to the servletcontainer's specific JspServlet which may not necessarily be mapped on the servlet name of jsp).
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>