Q In the following node I expect a lookup based on one of these attributes to be very fast, so I should get my data quickly.
<NODE attrib1="itemX" attrib2="itemY">valueN</NODE>
Now consider this node:
<NODE attrib1="itemX" attrib2="itemY">
<Data1>value</Data1>
<Data2>value</Data2>
<Data3>value</Data3>
•••
<DataN>value</DataN>
</NODE>
This would create a much larger working set, but I would expect the lookup to be just as fast. Is it a mistake to assume this? Or, would it be faster to partition the XML into multiple files like this:
Data1.xml
<NODE attrib1="itemX" attrib2="itemY">value</NODE>
Data2.xml
<NODE attrib1="itemX" attrib2="itemY">value</NODE>
Data3.xml
<NODE attrib1="itemX" attrib2="itemY">value</NODE>
DataN.xml
<NODE attrib1="itemX" attrib2="itemY">value</NODE>
Here each XML file contains just one node/value pair, but each has the same attributes to do lookups. Keep in mind that I would be caching the DOM in application space and would only need to actually load it from a disk at a specified refresh interval. Also, data would never be written to the DOM.
A You are correct in assuming this performance would be similar to that of the first example for finding the NODE element. Getting each value would be very fast, but is the performance increase over the complex XML worth having all the extra files? If you need all the values of a given NODE element, this would actually cause a major performance hit since the same query would need to be executed multiple times, once per document.
With the information you have provided, having the complex NODE element is the best solution. For more information, see Inside MSXML Performance.
Q There is a CSV file I want to automatically download and save from the Web on a daily basis. Right now I'm manually downloading it by specifying a full URL (https://www.someplace.com/somefile.csv) in a Microsoft® Internet Explorer window and choosing to save the file when prompted rather than opening it. How can I automate this process instead?
A Here's a VBScript program that will download an arbitrary text file and display it.
Dim HTTP
Set HTTP = CreateObject("Microsoft.XMLHTTP")
If WScript.Arguments.Count <> 1 Then
WScript.Echo "Usage: GetURL URL"
WScript.Quit
End If
HTTP.Open "GET", WScript.Arguments(0), False
HTTP.Send
If HTTP.statusText = "OK" Then
Wscript.Echo HTTP.responseText
Else
Wscript.Echo "Error getting page:" & HTTP.statusText
End If
See the Internet Explorer object model and XMLHTTP documentation on how to download and open binary files.
Q I am using the XMLDOM to get node name and values. I get a particular node from IXMLDOMNodeList , and when I call IXMLDOMNODE::get_nodeTypedValue I get contents of all the child nodes separated by spaces. Why has this been implemented in this way? How do I get content only for that node?
A Given this XML fragment, what do you want for every <node>?
<nodes>
<node>foo</node>
<node><a>apple</a></node>
<node><b>boy</b><c>cat</c></node>
</nodes>
You might want to use text property or maybe nodeValue on a given element. To get the name of the node you can use nodeName property. The nodeTypedValue property will return a typed value of all nodeValues of itself and its child nodes.
Q Do you know of any best practices or standards guide for XML schemas that would be helpful?
A The one most often mentioned on the Web is https://www.xfront.com/BestPracticesHomepage.html.
Q Is it possible for an XPath expression to be conditional? I have the following XPath expression, which I'm using in a Microsoft BizTalk™ Server Orchestration:
//SystemRefs/SystemRef[SystemID="SomeIDthatIsNotValid"]/EntityID
Sometimes this will return no nodes (by design). But because it returns no nodes, the Orchestration fails. I'd like to know if it is possible to design a query like this:
If(//SystemRefs/SystemRef[SystemID="SomeIDthatIsNotValid"]/
EntityID=null,"No data" //SystemRefs/
SystemRef[SystemID="SomeIDthatIsNotValid"]/EntityID)
A You are expecting to get the contents of the <EntityID> element if SomeIDthatIsNotValid is matched:
<SystemRefs>
<SystemRef>
<SystemID>
SomeIDthatIsNotValid
<EntityID>return this</EntityID>
</SystemID>
</SystemRef>
</SystemRefs>
Well, this XML structure is not a good practice. An element should either have a text node or a set of child nodes. Here it's a combination of text and another element, <EntityID>. It would be more appropriate to set up the XML like this:
<SystemRefs>
<SystemRef SystemID="SomeIDthatIsNotValid">
<EntityID>return this</EntityID>
</SystemRef>
<SystemRef SystemID='foo'>
<EntityID>do not return this</EntityID>
</SystemRef>
</SystemRefs>
Then you would use an XPath expression like the following:
//SystemRefs/SystemRef[@SystemID='SomeIDthatIsNotValid']/EntityID
You can always use xsl:if to do tests on the existence of elements or attributes and even content. For example:
<xsl:variable name="entity">
<xsl:value-of select="//SystemRefs/
SystemRef[@SystemID='SomeIDthatIsNotValid']/EntityID" />
</xsl:variable>
<xsl:if test="$entity='' or $entity='null'">
no data
</xsl:if>
You can also group the predicates in this form [][].
Q I have a page with two frames; one has a form in it, the other has script. I'd like to use the script to write some text into the form.
The form (in frame f2) looks like this:
<form name="GoForm" ID="GoForm">
<input type="text" name="inputBox" size="30" id="inputBox">
<input type="button" name="GoButton" value="Go"
OnClick="Go()" id="GoButton">
</form>
The script in (frame f1) looks like this:
<SCRIPT>
//alert(parent.f2.location.href);
parent.f2.GoForm.inputBox.value = "something";
</SCRIPT>
When I run the script, I get the error: "parent.f2.GoForm.inputBox is null or not an object" unless I uncomment the alert statement. I don't want to have to call alert here and I've tried doing things like
var myvar = parent.f2.location.href;
and
document.write(parent.f2.location.href);
What is the best solution?
A The second frame is not loaded by the time the script runs, so the objects don't exist. In other words, when the script is called in f1, the form on f2 hasn't been loaded. This happens because client script is processed sequentially along with HTML. You can put the code in a function and call it when the other frame loads. One way to do this would be to set up two files. The first, frame.html, would look like this:
<FRAMESET COLS ="30%,*">
<FRAME name="f1" src="controls.html"/>
<FRAME name="f2" src="home.html" onload="f1.doValue();"/>
</FRAMSET>
The loaded controls.html file would then contain the doValue function, as shown here:
function doValue()
{
parent.f2.GoForm.inputBox.value = "something";
}
The reason it worked when you ran the alert was that by the time you pressed OK on the alert box, the f2 frame and form had enough time to load. I got your page to work by modifying the controls.html page as follows:
<BODY onLoad="init()">
<!-- Controls go here -->
</BODY>
<SCRIPT>
function init() {
parent.f2.GoForm.inputBox.value = "something";
}
</SCRIPT>
You could also achieve the same effect by adding an onClick event to a button or link, like so:
<input type="button" value="Click Me"
onClick='parent.f2.GoForm.inputBox.value = "something"'>
Q I have an XMLNode with the following innerXML:
<rs:data xmlns:rs=" urn:schemas-microsoft-com:rowset ">
<z:row ows_ID="108" ows_Title="g1" ows_Description=""
ows_Owner="1" ows_OwnerIsUser="1"
ows_OwnerName="webqa" ows_OwnerGlobal="0" ows_Hidden="0"
xmlns:z="#RowsetSchema" />
<z:row ows_ID="109" ows_Title="g2" ows_Description=""
ows_Owner="1" ows_OwnerIsUser="1"
ows_OwnerName="webqa" ows_OwnerGlobal="0" ows_Hidden="0"
xmlns:z="#RowsetSchema" />
</rs:data>
How do I get the groupnames "g1" and "g2" from this xmldoc? I tried using the following code in Visual Basic®, but it failed.
For Each xmlnode In xmlnode.SelectNodes("ows_Title")
MessageBox.Show(xmlnode.InnerXml)
Next
A You have to give the full XPath expression for your select statement. Attributes are selected using @, as shown here:
SelectNodes("@ows_Title")
Depending on where you are in the document, you might have to give the full select path, like this:
("/data/row/@ows_Title")
But then you will have to use the XmlNameSpaceManager to define the namespace.
The correct syntax is:
For Each xmlnode In xmlnode.SelectNodes("//@ows_Title")
MessageBox.Show(xmlnode.InnerXml)
Next
You could also try something like this:
Dim attr as XmlNode
for each attr in xmlnode.SelectNodes("//@ows_Title")
MessageBox.Show(xmlnode.InnerXml)
next
Q How do I go about obtaining the current user name in an ASP or HTML page?
A Look at request.servervariables(LOGON_USER) at https://msdn.microsoft.com/library/en-us/iisref/html/psdk/asp/vbob5vsj.asp. Given appropriate security context, this gives you the logged-on user name. In ASP you can use the SERVERVARIABLES collection as follows:
Request.ServerVariables("LOGON_USER")
Q I have a Web page that displays some configuration data stored in a SQL Server™ database. Currently the data is generated by a scheduled task—a simple one-line command. I want to put a button on the Web page to manually execute the process and update the data on demand. I'm able to get it to work via client scripting using the wshell.run method, but the process needs to execute on the server and I can't get that to work.
A You can do it in the same way you make other SQL query calls. In this case, use xp_cmdshell. For instance, if you send the query
xp_cmdshell 'Dir c:\'
you will get back a directory listing of the C: drive on the machine running SQL Server. You can put any legal operating system command inside the single quotes, including a call to a batch (.bat or .cmd) file which resides on the SQL server. Remember to fully qualify all paths.
Q Using ASP, is there a way to expire a page so that if the user clicks the Back button on his browser either no page or a special page will display? I don't want the user to get a valid page when he clicks the Back button on Internet Explorer because a transaction might process a second time.
A Yes, you can expire a page by using the Response.Expires property. See https://msdn.microsoft.com/library/en-us/iisref/html/psdk/asp/asps4j72.asp for more details.
Got a question? Send questions and comments to webqa@microsoft.com. |