在 XSLT 1.0/2.0 的元素上具有多个命名空间的 select 元素
To select element with multiple Namespaces on an element with XSLT 1.0/2.0
我有输入 xml,其中包含具有多个命名空间的元素,
我需要将此输入 xml 转换为另一种 xml 格式。但是我不确定如何在 xpath 中将多个命名空间指定为 select 具有两个命名空间 "a" 和 "i"
的元素 AVResult 的值
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:u="http://docs.oasis-open.org/2004/01/ty.xsd">
<s:Header>
</s:Header>
<s:Body>
<AVResponse
xmlns="http://info.com/Contracts">
<AVResult
xmlns:a="http://NamespaceOne.com"
xmlns:i="http://NamespaceTwo.com">
<Errors
xmlns="http://schemas.Messages" />
<ErrorDetail>
<Code>1718</Code>
<Description>Con Types: Sum should equal 100%</Description>
</ErrorDetail>
<Status xmlns="http://schemas.BaseMessages">Success</Status>
<a:NewID>275373</a:NewID>
<a:Valn>
<a:Locs>
<a:Loc>
<a:Builds>
<a:Build>
<a:Totals>
<a:Rcv>11430888.8146038</a:Rcv>
</a:Totals>
</a:Build>
</a:Builds>
</a:Loc>
</a:Locs>
</a:Valn>
</AVResult>
</AVResponse>
</s:Body>
</s:Envelope>
这是我的 XSLT:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fo="http://service.fo.com/"
xmlns:ns1="http://info.com/Contracts"
xmlns:a="http://NamespaceOne.com"
xmlns:ns3="http://schemas.BaseMessages"
xmlns:i="http://NamespaceTwo.com"
exclude-result-prefixes="ns1 a s">
<xsl:output method="xml" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="s:Header">
</xsl:template>
<xsl:template match="s:Body/ns1:AVResponse">
<xsl:apply-templates select="@* | node()" />
</xsl:template>
<xsl:template match="a:AVResult">
<Builds>
<response-header>
<fo:response-messages>
<xsl:if
test="//Status='Success'">
<fo:response-message>
<fo:response-type>Status</fo:response-type>
<fo:response-code></fo:response-code>
<fo:response-description>
<xsl:value-of select="//AVResponse/AVResult/Status" />
</fo:response-description>
</fo:response-message>
</xsl:if>
<xsl:if test="//AVResponse/AVResult/Status='Error'">
<fo:response-message>
<fo:response-type>Status</fo:response-type>
<fo:response-code></fo:response-code>
<fo:response-description>
<xsl:value-of
select="//ns1:AVResponse/a:AVResult/ns3:Status" />
</fo:response-description>
</fo:response-message>
<xsl:for-each
select="//ns1:AVResponse/ns1:AVResult/ns3:Errors">
<fo:response-message>
<fo:response-type>
<xsl:value-of
select="//ns1:AVResponse/ns1:AVResult/ns3:Errors/ns3:ErrorDetail">
</xsl:value-of>
</fo:response-type>
<fo:response-code>
<xsl:value-of
select="//ns1:AVResponse/ns1:AVResult/ns3:Errors/ns3:ErrorDetail/ns3:Code">
</xsl:value-of>
</fo:response-code>
<fo:response-description>
<xsl:value-of
select="//ns1:AVResponse/ns1:AVResult/ns3:Errors/ns3:ErrorDetail/ns3:Description">
</xsl:value-of>
</fo:response-description>
</fo:response-message>
</xsl:for-each>
</xsl:if>
</fo:response-messages>
</response-header>
<!--<xsl:for-each select="//a:Locs/a:Loc"> -->
<Build>
<property>
<fo:itv-output>
<fo:estimated-construction-amt>
<fo:amount>
<xsl:value-of
select="//ns1:AVResponse/ns1:AVResult/a:Locs/a:Loc/a:Builds/a:Build/a:Totals/a:Rcv">
</xsl:value-of>
</fo:amount>
<fo:currency>USD</fo:currency>
</fo:estimated-construction-amt>
</fo:itv-output>
</property>
</Build>
<!-- </xsl:for-each> -->
</Builds>
</xsl:template>
</xsl:stylesheet>
这里,如何将两个命名空间包含到 select AVResult ?
AVResult 实际上有三个命名空间。它还采用其父节点 AVResponse (xmlns="http://info.com/Contracts") 的命名空间。但是,由于 AVResponse 的名称空间没有前缀,您必须在样式表标记中创建一个带有前缀的引用,您已经将其创建为 ns1。因此,任何时候您想要引用 AVResponse 或其任何子节点或孙节点时,您都必须使用 ns1 前缀。此外,您不能将 ns1 放在 exclude-result-prefixes 中并排除它。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:fo="http://service.fo.com/"
xmlns:ns1="http://info.com/Contracts"
xmlns:a="http://NamespaceOne.com"
xmlns:ns3="http://schemas.BaseMessages"
xmlns:i="http://NamespaceTwo.com"
exclude-result-prefixes="ns3 a i s b">
<xsl:template match="ns1:AVResult">
do stuff
</xsl:template>
我有输入 xml,其中包含具有多个命名空间的元素, 我需要将此输入 xml 转换为另一种 xml 格式。但是我不确定如何在 xpath 中将多个命名空间指定为 select 具有两个命名空间 "a" 和 "i"
的元素 AVResult 的值<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:u="http://docs.oasis-open.org/2004/01/ty.xsd">
<s:Header>
</s:Header>
<s:Body>
<AVResponse
xmlns="http://info.com/Contracts">
<AVResult
xmlns:a="http://NamespaceOne.com"
xmlns:i="http://NamespaceTwo.com">
<Errors
xmlns="http://schemas.Messages" />
<ErrorDetail>
<Code>1718</Code>
<Description>Con Types: Sum should equal 100%</Description>
</ErrorDetail>
<Status xmlns="http://schemas.BaseMessages">Success</Status>
<a:NewID>275373</a:NewID>
<a:Valn>
<a:Locs>
<a:Loc>
<a:Builds>
<a:Build>
<a:Totals>
<a:Rcv>11430888.8146038</a:Rcv>
</a:Totals>
</a:Build>
</a:Builds>
</a:Loc>
</a:Locs>
</a:Valn>
</AVResult>
</AVResponse>
</s:Body>
</s:Envelope>
这是我的 XSLT:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fo="http://service.fo.com/"
xmlns:ns1="http://info.com/Contracts"
xmlns:a="http://NamespaceOne.com"
xmlns:ns3="http://schemas.BaseMessages"
xmlns:i="http://NamespaceTwo.com"
exclude-result-prefixes="ns1 a s">
<xsl:output method="xml" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="s:Header">
</xsl:template>
<xsl:template match="s:Body/ns1:AVResponse">
<xsl:apply-templates select="@* | node()" />
</xsl:template>
<xsl:template match="a:AVResult">
<Builds>
<response-header>
<fo:response-messages>
<xsl:if
test="//Status='Success'">
<fo:response-message>
<fo:response-type>Status</fo:response-type>
<fo:response-code></fo:response-code>
<fo:response-description>
<xsl:value-of select="//AVResponse/AVResult/Status" />
</fo:response-description>
</fo:response-message>
</xsl:if>
<xsl:if test="//AVResponse/AVResult/Status='Error'">
<fo:response-message>
<fo:response-type>Status</fo:response-type>
<fo:response-code></fo:response-code>
<fo:response-description>
<xsl:value-of
select="//ns1:AVResponse/a:AVResult/ns3:Status" />
</fo:response-description>
</fo:response-message>
<xsl:for-each
select="//ns1:AVResponse/ns1:AVResult/ns3:Errors">
<fo:response-message>
<fo:response-type>
<xsl:value-of
select="//ns1:AVResponse/ns1:AVResult/ns3:Errors/ns3:ErrorDetail">
</xsl:value-of>
</fo:response-type>
<fo:response-code>
<xsl:value-of
select="//ns1:AVResponse/ns1:AVResult/ns3:Errors/ns3:ErrorDetail/ns3:Code">
</xsl:value-of>
</fo:response-code>
<fo:response-description>
<xsl:value-of
select="//ns1:AVResponse/ns1:AVResult/ns3:Errors/ns3:ErrorDetail/ns3:Description">
</xsl:value-of>
</fo:response-description>
</fo:response-message>
</xsl:for-each>
</xsl:if>
</fo:response-messages>
</response-header>
<!--<xsl:for-each select="//a:Locs/a:Loc"> -->
<Build>
<property>
<fo:itv-output>
<fo:estimated-construction-amt>
<fo:amount>
<xsl:value-of
select="//ns1:AVResponse/ns1:AVResult/a:Locs/a:Loc/a:Builds/a:Build/a:Totals/a:Rcv">
</xsl:value-of>
</fo:amount>
<fo:currency>USD</fo:currency>
</fo:estimated-construction-amt>
</fo:itv-output>
</property>
</Build>
<!-- </xsl:for-each> -->
</Builds>
</xsl:template>
</xsl:stylesheet>
这里,如何将两个命名空间包含到 select AVResult ?
AVResult 实际上有三个命名空间。它还采用其父节点 AVResponse (xmlns="http://info.com/Contracts") 的命名空间。但是,由于 AVResponse 的名称空间没有前缀,您必须在样式表标记中创建一个带有前缀的引用,您已经将其创建为 ns1。因此,任何时候您想要引用 AVResponse 或其任何子节点或孙节点时,您都必须使用 ns1 前缀。此外,您不能将 ns1 放在 exclude-result-prefixes 中并排除它。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:fo="http://service.fo.com/"
xmlns:ns1="http://info.com/Contracts"
xmlns:a="http://NamespaceOne.com"
xmlns:ns3="http://schemas.BaseMessages"
xmlns:i="http://NamespaceTwo.com"
exclude-result-prefixes="ns3 a i s b">
<xsl:template match="ns1:AVResult">
do stuff
</xsl:template>