开发者

xslt with xpath that get some information from xml file doesn't work in JavaScript

开发者 https://www.devze.com 2023-01-23 15:30 出处:网络
I\'ve got an xml file. It is meant for being transformed by xslt processor. The specific template is ready, however it use some information from two additional xml files. All information is used to pr

I've got an xml file. It is meant for being transformed by xslt processor. The specific template is ready, however it use some information from two additional xml files. All information is used to produce the proper output.

It works fine when I open the main xml file with my browser. The problem is: the result is just a fragment of website, it is an HTML element ready for being appended as a child. That is why I want to transform the xml with the xslt processor within a JavaScript function. Unfortunatelly, the result is half-way done. All what don't need the additional information from these two xml files imported by xpath expression is transformed well. The rest is shortly speaking absent.

JavaScript:

var xhttp = new XMLHttpRequest()
var xsltProcessor = new XSLTProcessor()
xhttp.open("GET", "contentTemplate.xsl", false)
xhttp.send()
xsltProcessor.importStylesheet(xhttp.responseXML)

function buildElement(what) {
var xmlDoc = document.implementation.createDocument("", "root", null)
xmlDoc.documentElement.appendChild(xmlDoc.createElement(what))

var resultDocumentFragment = xsltProcessor.transformToFragment(xmlDoc, document)
return resultDocumentFragment
}

xslt:

there is lots of stuff, I paste just the xslt with xpath expression

<xsl:variable name="extInfo" select="document('tagAvailableToAdd.xml')/root"/>
<xsl:for-each select="$extInfo/tag">
 <option>
  <xsl:attribute name="value"><xsl:value-of select="tagN开发者_开发技巧ame"/></xsl:attribute>
  <xsl:value-of select="description"/>
 </option>
</xsl:for-each>

and that is just absent. Just like no information was delivered.

EDIT:

it works in firefox, doesn't in chrome. I need to improve it. Actually, I don't know how.


xslt:

there is lots of stuff, I paste just the xslt with xpath expression

<xsl:variable name="extInfo" select="document('tagAvailableToAdd.xml')/root"/>

<xsl:for-each select="$extInfo/tag"> 
 <option> 
  <xsl:attribute name="value"><xsl:value-of

select="tagName"/>

and that is just absent. Just like no information was delivered.

Some possible reasons for this behaviour:

  1. The URI of the XML file is not the right one. This is a relative URI and this specific URI will mace the XSLT processor look for a file named 'tagAvailableToAdd.xml' and residing at the base-uri of the stylesheet. However, in this case the stylesheet is obtained dynamically and this means it doesn't have any base-uri. This is the most possible reason for the problem.

  2. The Javascript doesn't have permissions to access files in the local file system.

  3. The document() function isn't allowed by default by the XSLT processor.

  4. The text contained in the file is not a well-formed XML document.

  5. The top element of the XML file is not named root.

Solution: Specify an absolute URI as the argument to the document() function.


I thought I had solved the problem, however an issue in firefox has occured.

Nevertheless, I concern chrome my native browser, that is why i'm glad I made it work in this program. That is the change I implemented in JavaScript:

function talkToServer(address, synch, func) {
func = typeof(func) != 'undefined' ? func : null
xhttp.open(method, address, synch)
xhttp.onreadystatechange = func
xhttp.send()
}

function getXPath(query) {
return document.evaluate(query, xhttp.responseXML, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null)
}

function buildElement(what) {
var xmlDoc = document.implementation.createDocument("", "root", null)
xmlDoc.documentElement.appendChild(xmlDoc.createElement(what))

switch(what) {
case "windowElement":
talkToServer("tagAvailableToAdd.xml", false)
var additionalInfo = getXPath("/root/tag")
var aim = xmlDoc.documentElement.getElementsByTagName("windowElement")[0]
for(i=0;i<additionalInfo.snapshotLength;i++)
    aim.appendChild(additionalInfo.snapshotItem(i).cloneNode(true))

talkToServer("cssTemplates.xml", false)
additionalInfo = getXPath("/root/*")
aim.appendChild(xmlDoc.createElement("css"));
aim = aim.getElementsByTagName("css")[0]
for(i=0;i<additionalInfo.snapshotLength;i++)
    aim.appendChild(additionalInfo.snapshotItem(i).cloneNode(true))
break;
}
var resultDocumentFragment = xsltProcessor.transformToFragment(xmlDoc, document)
return resultDocumentFragment
}

in xslt now I have all information in , so there is no need to import any external info.

main function is buildElement. I'm sure everybody can see what it does. It'a aim is to provide sth I can "paste" to HTML document.

In chrome it works. In firefox says: Node cannot be used in a document other than the one in which it was created" code: "4, and points at return statement in getXPath function. I don't know how ti fix it, but who cares, it is just firefox (I know it's stupid). In IE it suck, because xhttp is XHttpRequest object, but I believe, that when I provide ActiveX it should give what I want.

If you feel you can help me with the firefix issue, write a comment.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号