2

我正在尝试使用数据视图 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?

4

2 回答 2

2

看起来结果是一个字符串,而不是需要处理的 XML。如果不查看结果 xml,我无法确定。

尝试添加<xmp><xsl:copy-of select="." /></xmp>并发布结果。

你可以删除肥皂上的匹配:信封等并用匹配“*”替换。

然后在里面添加一个

<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,我不能确定)这都是为了调试。

于 2010-03-03T20:20:34.940 回答
1

在查看您正在使用的服务时,它确实返回字符串中的值,< 使其看起来像 XML。我无法想象他们为什么要这样做,但是您需要将字符串解析为 XML 才能处理它。没有本机 XSLT 函数可以执行此操作,因此您必须使用扩展函数。我不知道微软有哪一个,所以你必须自己写。

幸运的是,这篇文章中有一个很好的例子来说明这个确切的问题。这个人最终使用了一个用 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="&lt;Empty /&gt;";
        }
        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)" />

我不能保证自定义功能会完全按照您的需要工作,但希望它能让您接近。

于 2010-03-05T17:03:19.863 回答