Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我无法从带名称空间的XML中选择节点值_Xml_Xslt_Xpath_Namespaces_Xslt 1.0 - Fatal编程技术网

我无法从带名称空间的XML中选择节点值

我无法从带名称空间的XML中选择节点值,xml,xslt,xpath,namespaces,xslt-1.0,Xml,Xslt,Xpath,Namespaces,Xslt 1.0,我无法将SOAP响应XML转换为纯文本字符串。 我从XLST开始,我已经读了所有我能读到的东西。显然,我需要完成的事情很简单,但所有的例子都比我的上下文简单得多 首先,我接触到一个web服务Bing Maps反向地理编码,它返回以下XML结构: <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <ReverseGeocodeResponse xmlns="h

我无法将SOAP响应XML转换为纯文本字符串。 我从XLST开始,我已经读了所有我能读到的东西。显然,我需要完成的事情很简单,但所有的例子都比我的上下文简单得多

首先,我接触到一个web服务Bing Maps反向地理编码,它返回以下XML结构:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <ReverseGeocodeResponse xmlns="http://dev.virtualearth.net/webservices/v1/geocode/contracts">
      <ReverseGeocodeResult xmlns:a="http://dev.virtualearth.net/webservices/v1/geocode" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <BrandLogoUri xmlns="http://dev.virtualearth.net/webservices/v1/common">
          http://dev.virtualearth.net/Branding/logo_powered_by.png
        </BrandLogoUri>
        <ResponseSummary xmlns="http://dev.virtualearth.net/webservices/v1/common">
          <AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
          <Copyright>(...)</Copyright>
          <FaultReason i:nil="true" />
          <StatusCode>Success</StatusCode>
          <TraceId>(...)</TraceId>
        </ResponseSummary>
        <a:Results xmlns:b="http://dev.virtualearth.net/webservices/v1/common">
          <b:GeocodeResult>
            <b:Address>
              <b:AddressLine>(...)</b:AddressLine>
              <b:AdminDistrict>SP</b:AdminDistrict>
              <b:CountryRegion>Brasil</b:CountryRegion>
              <b:District />
              <b:FormattedAddress>(...)</b:FormattedAddress>
              <b:Locality>Campinas</b:Locality>
              <b:PostalCode>13069-380</b:PostalCode>
              <b:PostalTown />
            </b:Address>
            <b:BestView>(...)</b:BestView>
            <b:Confidence>Medium</b:Confidence>
            <b:DisplayName>(...)</b:DisplayName>
            <b:EntityType>Address</b:EntityType>
            <b:Locations>(...)</b:Locations>
            <b:MatchCodes xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
              <c:string>Good</c:string>
            </b:MatchCodes>
          </b:GeocodeResult>
          <b:GeocodeResult>
            (...)
          </b:GeocodeResult>
        </a:Results>
      </ReverseGeocodeResult>
    </ReverseGeocodeResponse>
  </s:Body>
</s:Envelope>
我知道这应该只返回第一个b:Location和b:AdminDistrict节点,这很完美。但是当我尝试这样做时,结果是XML中的所有文本都没有标记,只是连接了文本。这种方法的一些变体只返回两个xsl:value标记之间的“-”片段

我做错了什么?这是否与无限的名称空间有关?

样式表中发生了什么

原始代码中发生的情况是:您编写的模板与输入XML中的任何内容都不匹配。这意味着此模板中的代码永远不会执行。相反,对于输入XML中的所有节点,默认值为

内置模板遍历树,只输出所有文本内容。这就是为什么你最终会:

但是当我尝试这样做时,结果是XML中的所有文本都没有标记,只是连接了文本

要防止出现这种情况,请编写一个与所有文本匹配的空模板:

<xsl:template match="text()"/>
不匹配输入XML中的任何节点。对于上面的路径表达式,XPath处理器希望ReverseGeocodeResponse和ReverseGeoCodeResult不在名称空间中。但对于您的输入XML,这是不正确的:

<ReverseGeocodeResponse xmlns="http://dev.virtualearth.net/webservices/v1/geocode/contracts">
    <ReverseGeocodeResult xmlns:a="http://dev.virtualearth.net/webservices/v1/geocode">
但效果不同。这为XSLT样式表中的元素定义了默认名称空间。但您要做的是为XPath表达式定义一个默认名称空间。这也是可能的-哪一个

仅在XSLT2.0中可用 因为您的输入XML有多个默认命名空间,所以没有用处 样式表

您看到的xml的混乱是由于内置模板的复杂性造成的。通常,如果您只想处理文档中的特定元素,则需要捕获根元素,然后有选择地使用应用模板

另外,之所以看不到预期值,是因为ReverseGeocodeResponse和ReverseGeocodeResult实际上是xmlns名称空间http://dev.virtualearth.net/webservices/v1/geocode/contracts -您需要适当调整xslt我添加了别名zz:


太好了!已经测试过了,效果很好!非常感谢,我将通读您的答案并尽力理解细节,但您提供的样式表完全符合需要。@PauloAvelar不客气。如果您能阅读详细信息,我将不胜感激-它们花费了很多时间:-。
/s:Envelope/s:Body/ReverseGeocodeResponse/ReverseGeocodeResult/a:Results/b:GeocodeResult/b:Address"
<ReverseGeocodeResponse xmlns="http://dev.virtualearth.net/webservices/v1/geocode/contracts">
    <ReverseGeocodeResult xmlns:a="http://dev.virtualearth.net/webservices/v1/geocode">
<xsl:stylesheet version="1.0"
    xmlns="http://dev.virtualearth.net/webservices/v1/common">
<xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:a="http://dev.virtualearth.net/webservices/v1/geocode"
        xmlns:b="http://dev.virtualearth.net/webservices/v1/common"
        xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
        xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:con="http://dev.virtualearth.net/webservices/v1/geocode/contracts">

    <xsl:output method="text"/>

    <xsl:template match="/s:Envelope/s:Body/con:ReverseGeocodeResponse/con:ReverseGeocodeResult/a:Results/b:GeocodeResult/b:Address">
        <xsl:value-of select="b:Locality"/> - <xsl:value-of select="b:AdminDistrict"/>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>
Campinas - SP
<xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns="http://dev.virtualearth.net/webservices/v1/common"
        xmlns:a="http://dev.virtualearth.net/webservices/v1/geocode"
        xmlns:b="http://dev.virtualearth.net/webservices/v1/common"
        xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
        xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:zz="http://dev.virtualearth.net/webservices/v1/geocode/contracts">

  <xsl:template match="/">
    <xsl:apply-templates select="/s:Envelope/s:Body/zz:ReverseGeocodeResponse/zz:ReverseGeocodeResult/a:Results/b:GeocodeResult/b:Address"/>
  </xsl:template>

  <xsl:template match="b:Address">
    <xsl:value-of select="b:Locality"/> - <xsl:value-of select="b:AdminDistrict"/>
  </xsl:template>

</xsl:stylesheet>