我无法从带名称空间的XML中选择节点值
我无法将SOAP响应XML转换为纯文本字符串。 我从XLST开始,我已经读了所有我能读到的东西。显然,我需要完成的事情很简单,但所有的例子都比我的上下文简单得多 首先,我接触到一个web服务Bing Maps反向地理编码,它返回以下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
<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>