我正在尝试使用数据视图Web部件(通过SPD 2007)来使用基于SOAP的Web服务的结果,并使用XSL转换呈现所述结果的部分。我遇到的问题是设计人员没有多大帮助,因为Web服务的模式实际上并不包含结果的元素,因此无法将数据源拖放到Web部件中,我试过的手动变换不起作用。
以下是Web服务的定义:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetQuote xmlns="http://www.webserviceX.NET/">
<symbol>string</symbol>
</GetQuote>
</soap:Body>
</soap:Envelope>
响应的定义:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetQuoteResponse xmlns="http://www.webserviceX.NET/">
<GetQuoteResult>string</GetQuoteResult>
</GetQuoteResponse>
</soap:Body>
</soap:Envelope>
查询定义没有问题 - 您只需将股票代码符号作为字符串提供。不过,你会在结果中看到我在说什么。它将结果定义为字符串。
在SPD2007中,数据源几乎只包含soap:Envelope/soap:Body/GetQuoteResponse/GetQuoteResult
,但结果字符串中包含的实际结果如下所示:
<StockQuotes>
<Stock>
<Symbol>MSFT</Symbol>
<Last>28.465</Last>
<Date>3/3/2010</Date>
<Time>1:24pm</Time>
<Change>+0.005</Change>
<Open>28.52</Open>
<High>28.61</High>
<Low>28.35</Low>
<Volume>28380812</Volume>
<MktCap>249.7B</MktCap>
<PreviousClose>28.46</PreviousClose>
<PercentageChange>+0.02%</PercentageChange>
<AnnRange>14.87 - 31.50</AnnRange>
<Earns>1.815</Earns>
<P-E>15.68</P-E>
<Name>Microsoft Corpora</Name>
</Stock>
</StockQuotes>
我已经尝试在数据视图Web部件中设置这样的XSL样式表:
<xsl:stylesheet xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ddw1="http://www.webserviceX.NET/"
version="1.0"
exclude-result-prefixes="xsl msxsl ddwrt"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:asp="http://schemas.microsoft.com/ASPNET/20"
xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:SharePoint="Microsoft.SharePoint.WebControls"
xmlns:ddwrt2="urn:frontpage:internal">
<xsl:output method="html" indent="yes"/>
<xsl:param name="dvt_apos">'</xsl:param>
<xsl:template match="/soap:Envelope/soap:Body/ddw1:GetQuoteResponse">
<xsl:value-of select="*" />
</xsl:template>
</xsl:stylesheet>
这几乎与您期望的一样:它呈现整个结果字符串。但是,如果我替换
<xsl:template match="/soap:Envelope/soap:Body/ddw1:GetQuoteResponse">
<xsl:value-of select="*" />
</xsl:template>
与
<xsl:template match="/soap:Envelope/soap:Body/ddw1:GetQuoteResponse">
<xsl:value-of select="//Symbol" />
</xsl:template>
我一无所获。这是怎么回事?如何在没有模式的情况下使用XSL在字符串结果中选择XML?
答案 0 :(得分:2)
看起来结果是一个字符串,而不是需要处理的XML。如果不查看结果xml,我无法确定。
尝试添加<xmp><xsl:copy-of select="." /></xmp>
并发布结果。
你可以删除soap:Envelope等上的匹配,并用匹配“*”替换。
然后在里面添加一个
<p>Symbol:<xsl:value-of select="/StockQuotes/Stock/Symbol" /></p>
如果不提供值,则匹配不正确。也试试
<p>Symbol:<xsl:value-of select="/soap:Envelope/soap:Body/ddw1:GetQuoteResponse/StockQuotes/Stock/Symbol" /></p>
在一天结束时,你想得到类似的东西(没有看到原始的xml,我无法确定) 这都是为了调试。
答案 1 :(得分:1)
在查看service you are using时,它确实返回字符串中的值&lt;使它看起来像XML。我无法想象为什么他们会这样做,但你需要将字符串解析为XML以便处理它。没有本机XSLT功能可以执行此操作,因此您必须使用扩展功能。我不知道微软的一个,所以你必须自己编写。
幸运的是,这个确切的问题有一个good example in this post。这个人最终使用用c#编写的自定义扩展函数将字符串转换为XML,然后将其传递回XSLT进行常规处理。他们使用的自定义功能是:
<msxml:script language="CSharp" implements-prefix="cd">
<msxml:using namespace="System.IO" />
public XPathNodeIterator parse(string data) {
if(data==null || data.Length==0) {
data="<Empty />";
}
StringReader stringReader = new StringReader(data);
XPathDocument xPathDocument = new XPathDocument(stringReader);
XPathNavigator xPathNavigator = xPathDocument.CreateNavigator();
XPathExpression xPathExpression = xPathNavigator.Compile("/");
XPathNodeIterator xPathNodeIterator = xPathNavigator.Select(xPathExpression);
return xPathNodeIterator;
}
</msxml:script>
然后你在字符串上调用函数:
<xsl:variable name="theXML" select="string(/string)" />
<xsl:variable name="list" select="cd:parse($theXML)" />
我无法保证自定义功能能够完全按照您的需要运行,但它应该会让您接近。