使用Python下的XSLT API进行web开发的简单教程

发表于 5年以前  | 总阅读数:855 次

Kafka 样式的 soap 端点

Christopher Dix 所开发的"Kafka ― XSL SOAP 工具箱"(请参阅 参考资料)是一种用于构造 SOAP 端点的 XSLT 框架。它只涵盖了 SOAP 1.1,但 Kafka 端点演示了传递 UserLand SOAP 验证器(UserLand SOAP Validator)的能力,并且根据 SOAP 1.2 对它进行更新似乎并不太困难。 清单 1展示了一个样本 Kafka 端点:求两数之和的 SOAP 服务器(一个典型而简单的 SOAP 样本)。

清单 1. 求两数之和的 Kafka SOAP 端点


    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
     xmlns:method="http://www.topxml.com/"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    >
      <!-- add.xsl : Kafka SOAP Endpoint Example, with modifications -->
      <!-- Import soap.xsl to use the framework -->
      <xsl:import href="kafka/soap.xsl"/>
      <xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes"/>
      <!-- Define the global variables for the framework -->
      <xsl:variable name="Method">Add</xsl:variable>
      <xsl:variable name="MethodNS">http://www.topxml.com/</xsl:variable>
      <!-- Add : Add two numbers and return the sum -->
      <!-- Function Add( A as Double, B as Double ) as Double -->
      <xsl:template name="ProcessPayload">
       <xsl:param name="Payload"/>
       <xsl:for-each select="$Payload">
         <!-- This is how to retrieve parameters from the input -->
         <xsl:variable name="A" select="number(A|method:A)"/>
         <xsl:variable name="B" select="number(B|method:B)"/>
         <!-- The WriteParameter template takes the qualified name
           for a response parameter as well as its value and
           a QName specifying the tpe (for the xsi:type attribute) -->
         <xsl:call-template name="WriteParameter">
          <xsl:with-param name="p" select="'Result'"/>
          <xsl:with-param name="v" select="$A + $B"/>
          <xsl:with-param name="t" select="'xsd:double'"/>
         </xsl:call-template>
       </xsl:for-each>
      </xsl:template>

    </xsl:stylesheet>

XSLT 端点导入 SOAP 框架(文件 kafka/soap.xsl),然后设置该框架将要使用的参数,并设置它在处理构成 SOAP 消息的整个 XML 文档的过程中将要分派的模板。全局变量 Method 和 MethodNS 声明了组成消息的 XML 元素。在处理完 SOAP 信封之后,该框架调用 ProcessPayload 模板,该模板传入了 XML 主体的有效负载。 xsl:for-each 是将上下文切换成想要的节点的标准技巧。参数 A 和 B 是使用简单 XPaths 从这个元素读取的,而框架被再次调用以帮助写出响应参数。 WriteParameter 模板让您指定元素名称、数据类型和每个输出参数的值。本示例中的响应值是将两个输入参数相加所得的结果。

将这个端点部署为服务器相当于设置一个 HTTP 侦听器。Python 的 BaseHTTPServer 模块向您提供了所需的机制,能够轻而易举地处理该协议的 HTTP 部分。请参阅 清单 2。

清单 2. 用于清单 1 中所实现的 Kafka SOAP 端点的 Python HTTP 框架


    #HTTP Listener code for SOAP server
    import BaseHTTPServer
    #The processor class is the core of the XSLT API
    from Ft.Xml.Xslt import Processor
    #4XSLT uses an InputSource system for reading XML
    from Ft.Xml import InputSource
    SOAP_IMPL_FILE = "add.xsl"
    class KafkaSoapHandler(BaseHTTPServer.BaseHTTPRequestHandler):
      def init(cls):
        from Ft.Lib import Uri
        #Set up a processor instance to use
        KafkaSoapHandler.processor = Processor.Processor()
        #Load it with add.xsl
        add_uri = Uri.OsPathToUri(SOAP_IMPL_FILE, attemptAbsolute=1)
        transform = InputSource.DefaultFactory.fromUri(add_uri)
        KafkaSoapHandler.processor.appendStylesheet(transform)
        #Now the processor is prepped with a transform and can be used
        #over and over for the same transform
        return
      #Make init() a static method of the class
      init = classmethod(init)
      def do_POST(self):
        clen = self.headers.getheader('content-length')
        if clen:
          clen = int(clen)
        else:
          print 'POST ERROR: missing content-length'
          return
        if self.path != '/add':
          self.send_error(404)
        input_body = self.rfile.read(clen)
        #input_body is the request SOAP envelope and contents
        response_body = self._run_through_kafka(input_body)
        #response_body is the response SOAP envelope and contents
        self._send_response(200, 'OK', response_body)
        return
      def _run_through_kafka(self, body):
        #In 4Suite all InputSources have base URIs in case they refer to
        #other URIs in some way and resolution is required.
        #The SOAP messages will not have any such URI references,
        #So use a dummy base URI
        source = InputSource.DefaultFactory.fromString(body, "urn:dummy")
        response = self.processor.run(source)
        return response
      def _send_response(self, code, msg, body):
        #Prepare a normal response
        self.send_response(200, 'OK')
        #Send standard HTP headers
        self.send_header('Content-type','text/html; charset=utf-8')
        self.send_header("Connection", "close")
        self.send_header("Accept-Ranges", "bytes")
        self.send_header('Content-length', len(body)-1)
        self.end_headers()
        #Send the response prepared by the SOAP end point
        self.wfile.write(body)
        return

    listen_on_port = 8888
    #Set up to run on local machine
    server_address = ('127.0.0.1', listen_on_port)
    KafkaSoapHandler.init()
    httpd = BaseHTTPServer.HTTPServer(server_address, KafkaSoapHandler)
    print "Listening on port", listen_on_port
    #Go into a the main event loop
    httpd.serve_forever()

我们详细地注释了该清单,因此它应该是易于理解的。请注意,这段代码非常简单,这是因为它仅需处理该协议的 HTTP 部分,而将 XML 和 SOAP 部分的工作交由 Kafka 框架完成。该服务器专用于一个端点,因此它只须对 XSLT 转换进行一次解析和设置,然后它就可以简单地反复为每次新的请求运行该转换。这就是将处理器设置迁移到特殊的类方法中的原因,处理程序一注册到服务器就立即调用该方法。 classmethod 内置方法是 Python 2.2 中的新功能,实际上该版本是本例和后面的示例所必需的版本。它提供了隐式类对象 (cls) ,您可以将静态数据(如已准备好的处理器实例)附加到该对象上,然后通常可以通过普通方法上的 self 实例引用来使用该数据。

我们使用 SOAPpy 0.10.1 的最新发行版(请参阅 参考资料)测试了该端点,该发行版具有许多很棒的新功能,稍后我们将在本专栏中进行讨论。 清单 3是使用该端点的 SOAPpy 客户机。打开一个命令 shell 并为服务器运行 python listing2.py。然后打开另一个 shell 并运行 python listing3.py,该命令将报告正确的响应,形如 Add result: 7.0。

清单 3: 用于求两数之和的 SOAPpy 客户机


    import SOAPpy
    ENDPOINT = "http://localhost:8888/add"
    ADD_NS = "http://www.topxml.com/"

    remote = SOAPpy.SOAPProxy(ENDPOINT, namespace=ADD_NS)
    print "Add result:", remote.Add(A=3, B=4)

使用描述

正如我们先前所说的,不仅 XML 中的有效负载是有用的 Web 服务特性,描述也是有用的特性。 清单 4是一个用于添加服务的 WSDL 文件,它是根据 Christopher Dix 的原始文件修改而得到的。它是 WSDL 1.1 版本的。

清单 4. 用于添加服务的 WSDL


    <?xml version="1.0" encoding="UTF-8"?>
    <definitions name="adder"
     targetNamespace="http://www.topxml.com/"
     xmlns:tns="http://www.topxml.com/"
     xmlns:xsd="http://www.w3.org/1999/XMLSchema"
     xmlns="http://schemas.xmlsoap.org/wsdl/">
     <message name="Add">
      <part name="A" type="xsd:double" />
      <part name="B" type="xsd:double" />
     </message>
     <message name="AddResponse">
      <part name="param" type="xsd:double" />
     </message>
     <portType name="adder-port-type">
      <operation name="Add">
       <input message="tns:Add" />
       <output message="tns:AddResponse" />
      </operation>
     </portType>
     <binding name="adder-soap-binding" type="tns:adder-port-type"
          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
             style="rpc"/>
      <operation name="Add">
       <soap:operation soapAction="http://tempuri.org/"/>
       <input>
        <soap:body use="encoded" namespace="http://www.topxml.com/"
         encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
       </input>
       <output>
        <soap:body use="encoded" namespace="http://www.topxml.com/"
         encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
       </output>
      </operation>
     </binding>
     <service name="adder-service">
      <port name="adder-port" binding="tns:adder-soap-binding">
       <soap:address location="http://127.0.0.1:8888/add"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
      </port>
     </service>
    </definitions>

清单 5提供了一个为端点用户呈现有用信息的 XSLT 脚本。它是从先前的 developerWorks 文章"WSDL processing with XSLT"(请参阅 参考资料)中所开发的一个转换改编而来的。它使用了许多自由方式(liberty)和快捷方式(尤其是在它处理 WSDL 上下文中的限定名时),但它也许可用于目前使用的大多数 WSDL 1.1 文件。

清单 5. XSLT 脚本


    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version='1.0'
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    >
     <xsl:output method='html'/>
     <!-- Lookup tables for messages, portTypes, bindings and services -->
     <xsl:key name='message' match="wsdl:definitions/wsdl:message"
          use='@name'/>
     <xsl:key name='port-type' match="wsdl:definitions/wsdl:portType"
          use='@name'/>
     <xsl:key name='binding' match="wsdl:definitions/wsdl:binding"
          use='@name'/>
     <xsl:key name='service' match="wsdl:definitions/wsdl:service"
          use='@name'/>
     <xsl:template match='/'>
      <html>
      <head>
       <title>
    Service summary: <xsl:value-of select='wsdl:definitions/@name'/>
       </title>
       <meta http-equiv="content-type" content="text/html"
          charset="UTF-8"/>
      </head>
      <body>
        <h1>
    Service summary: <xsl:value-of select='wsdl:definitions/@name'/>
        </h1>
        <p><xsl:value-of select='wsdl:definitions/@documentation'/></p>
        <xsl:apply-templates select="wsdl:definitions/wsdl:service"/>
      </body>
       </html>
      </xsl:template>
      <xsl:template match='wsdl:service'>
       <div style="background: #ccffff">
        Service "<xsl:value-of select='@name'/>" hosted at
       <code>
        <xsl:value-of select='wsdl:port/soap:address/@location'/>
       </code>
        <xsl:variable name="binding"
         select="key('binding',
               substring-after(wsdl:port/@binding, ':'))"
        />
        <xsl:variable name="port-type"
         select="key('port-type',
               substring-after($binding/@type, ':'))"
        />
        <xsl:apply-templates select="$port-type/wsdl:operation"/>
       </div>
      </xsl:template>
     <xsl:template match='wsdl:operation'>
      <p>Operation "<b><xsl:value-of select='@name'/></b>" message details:</p>
      <!-- Yes, should sue CSS, but keep this example simple -->
      <table border="1" width="50%">
       <tbody>
        <xsl:if test="wsdl:input">
         <xsl:call-template name='message-role'>
          <xsl:with-param name="role-node" select="wsdl:input"/>
         </xsl:call-template>
        </xsl:if>
        <xsl:if test="wsdl:output">
         <xsl:call-template name='message-role'>
          <xsl:with-param name="role-node" select="wsdl:output"/>
         </xsl:call-template>
        </xsl:if>
        <xsl:if test="wsdl:fault">
         <xsl:call-template name='message-role'>
          <xsl:with-param name="role-node" select="wsdl:fault"/>
         </xsl:call-template>
        </xsl:if>
       </tbody>
      </table>
     </xsl:template>
     <xsl:template name='message-role'>
      <xsl:param name="role-node"/>
      <xsl:variable name="role-name"
             select="local-name($role-node)"/>
      <xsl:variable name="message"
       select="key('message',
           substring-after($role-node/@message, ':'))"
       />
      <tr>
       <td><xsl:value-of select='$role-name'/></td>
       <td>
        <table width="100%">
         <xsl:apply-templates select="$message/wsdl:part"/>
        </table>
       </td>
      </tr>
     </xsl:template>
     <xsl:template match='wsdl:part'>
      <tr>
       <td width="50%"><b><xsl:value-of select='@name'/></b></td>
       <td><xsl:value-of select='@type'/></td>
      </tr> 
     </xsl:template>
    </xsl:stylesheet>

通常在 Web 服务本身所在的主机上提供该服务人性化的 WSDL 描述是很方便的。 清单 6是 清单 2的变体,它也完成这一任务。它实际上提供三种功能:

  1. 对于端口 9000 上的 GET 请求:提供该 Web 服务调用消息的易于理解的描述
  2. 对于端口 8888 上的 GET 请求:提供未经处理的 WSDL 文件
  3. 对于端口 8888 上的 POST 请求:执行 SOAP 请求。

清单 6. 清单 2 的变体


    #HTTP Listener code for SOAP server
    import BaseHTTPServer
    #The processor class is the core of the XSLT API
    from Ft.Xml.Xslt import Processor
    #4XSLT uses an InputSource system for reading XML
    from Ft.Xml import InputSource
    SOAP_IMPL_FILE = "add.xsl"
    WSDL_FILE = "listing4.xml"
    HTML_VIEW_TRANSFORM = "listing5.xslt"
    class KafkaSoapHandler(BaseHTTPServer.BaseHTTPRequestHandler):
      def init(cls):
        from Ft.Lib import Uri
        #Set up a processor instance to use
        cls.processor = Processor.Processor()
        #Load it with add.xsl
        add_uri = Uri.OsPathToUri(SOAP_IMPL_FILE, attemptAbsolute=1)
        transform = InputSource.DefaultFactory.fromUri(add_uri)
        cls.processor.appendStylesheet(transform)
        #Now the processor is prepped with a transform and can be used
        #over and over for the same transform
        #Prep for WSDL requests
        cls.wsdl = open(WSDL_FILE).read()
        return
      #Make init() a static method of the class
      init = classmethod(init)
      def do_POST(self):
        clen = self.headers.getheader('content-length')
        if clen:
          clen = int(clen)
        else:
          print 'POST ERROR: missing content-length'
          return
        if self.path != '/add':
          self.send_error(404)
        input_body = self.rfile.read(clen)
        #input_body is the request SOAP envelope and contents
        response_body = self._run_through_kafka(input_body)
        #response_body is the response SOAP envelope and contents
        _send_response(self, 200, 'OK', response_body)
        return
      def do_GET(self):
        #response_body is the WSDL file
        _send_response(self, 200, 'OK', self.wsdl)
        return

      def _run_through_kafka(self, body):
        #In 4Suite all InputSources have base URIs in case they refer to
        #other URIs in some way and resolution is required.
        #The SOAP messages will not have any such URI references,
        #So use a dummy base URI
        source = InputSource.DefaultFactory.fromString(body, "urn:dummy")
        response = self.processor.run(source)
        return response
    class HtmlHandler(BaseHTTPServer.BaseHTTPRequestHandler):
      def init(cls):
        from Ft.Lib import Uri
        #Perform the transform once and store the result
        processor = Processor.Processor()
        html_desc_uri = Uri.OsPathToUri(HTML_VIEW_TRANSFORM,
                        attemptAbsolute=1)
        transform = InputSource.DefaultFactory.fromUri(html_desc_uri)
        processor.appendStylesheet(transform)
        wsdl_uri = Uri.OsPathToUri(WSDL_FILE, attemptAbsolute=1)
        source = InputSource.DefaultFactory.fromUri(wsdl_uri)
        cls.html_desc = processor.run(source)
        return
      #Make init() a static class method
      init = classmethod(init)
      def do_GET(self):
        #response_body is the WSDL file
        _send_response(self, 200, 'OK', self.html_desc)
        return
    #Turn _send_response into a global function
    #for sharing between the classes
    def _send_response(handler, code, msg, body):
        #Prepare a normal response
        handler.send_response(200, 'OK')
        #Send standard HTP headers
        handler.send_header('Content-type', 'text/html; charset=utf-8')
        handler.send_header("Connection", "close")
        handler.send_header("Accept-Ranges", "bytes")
        handler.send_header('Content-length', len(body)-1)
        handler.end_headers()
        #Send the response prepared by the SOAP end point
        handler.wfile.write(body)
        return

    def soap_listener_function():
      listen_on_port = 8888
      #Set up to run on local machine
      server_address = ('127.0.0.1', listen_on_port)
      KafkaSoapHandler.init()
      httpd = BaseHTTPServer.HTTPServer(server_address, KafkaSoapHandler)
      print "Listening for GET and POST on port", listen_on_port
      #Go into a the main event loop
      httpd.serve_forever()
    def html_listener_function():
      listen_on_port = 9000
      #Set up to run on local machine
      server_address = ('127.0.0.1', listen_on_port)
      HtmlHandler.init()
      httpd = BaseHTTPServer.HTTPServer(server_address, HtmlHandler)
      print "Listening for GET on port", listen_on_port
      #Go into a the main event loop
      httpd.serve_forever()
      return
    import time
    from threading import Thread
    soap_thread = Thread(None, soap_listener_function)
    html_thread = Thread(None, html_listener_function)
    soap_thread.start()
    #Pause before spawning the next thread
    time.sleep(1)
    html_thread.start()

通过在服务器上定义 do_GET 和 do_POST ,您可以在单个服务器实例上处理 GET 和 POST 请求,但是因为所使用的简单事件循环的性质,您可以使用线程技术在不同端口上进行侦听。这让您同时运行两个服务器实例。线程技术是方法之一,而使用异步事件处理程序是另一种方法。Python 2.2 为更轻松地支持后一种技术而引入了 asyncore 模块,我们在本专栏的上一篇文章中介绍了这种方法(请参阅 参考资料)。这一次我们将举例说明线程技术的用法。关于使用线程技术还是使用异步技术的问题,Python 2.2 文档提出了很好的建议。

仅当您的程序很大程度上受 I/O 限制时,[异步方法才是] 真正实用的。如果您的程序受处理器限制,那么抢先式调度的线程可能是您所真正需要的。但是,网络服务器很少受处理器限制。

图 1显示了易于理解的 Web 服务描述的浏览器视图。

2015415110404662.jpg \(572×370\)

结束语

请将这一切都看作实验素材。Kafka 已经相当落伍了 ― 它似乎从 2001 年以来就没有得到过维护,并且它使用了相当差劲的 XSLT 样式(其作者坦率地承认自己是个 XSLT 菜鸟)。但其思想是非常有用的,并且很有价值。只需要作很小的努力就可以将它更新到 SOAP 1.2 并扩展其能力。我们所提供的 WSDL 表示转换也只是一个起点。也可以将它更新到 WSDL 1.2 并可扩展它以显示关于 Web 服务的更多信息。还应该更新它以利用名称空间轴和其它 XSLT 功能以便进行更为正确的处理。

XSLT 是一个沙箱,使用各种语言和环境的开发人员都可以在其中施展身手。Kafka 是由一位坚定的 .NET 开发人员开发的,但我们也可以很快地学会它和利用它。这就是拥有一种既可以处理 XML 也可处理 Web 服务的通用语言(lingua franca)的威力。我们预计可以使用用于 Web 服务的 XSLT 模块的领域将继续扩展。如果是这样,本文所提供的基本技术可能会促使 Python 程序员们马上使用这些有用的技术。

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237269次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8108次阅读
 目录