我有一个XML输入文件,我在其中获得了一些名称空间,我想用另一个使用XSLT替换它们。其实我是新的XSLT,所以无法找到合适的解决方案。下面是我想要的XML输入有效负载和输出有效负载。任何人都可以帮助我。
输入有效负载:
<ns:createOrderResponse xmlns:ns="http://services.oms.ecom.ecc.com"><ns:return type="com.ecc.ecom.oms.beans.xsd.CreateOrderResponse"><ns:omsGeneratedOrderId xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" /><ns:responseCode>99</ns:responseCode><ns:responseDesc>INVALID ORDER</ns:responseDesc><ns:sellerSiteId>10196</ns:sellerSiteId><ns:serverProcElapsedTime>8</ns:serverProcElapsedTime><ns:siteGeneratedOrderId xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" /><ns:subResponse><responseCode xmlns="http://beans.oms.ecom.ecc.com/xsd">1144</responseCode><responseDescription xmlns="http://beans.oms.ecom.ecc.com/xsd">Order Total mismatch</responseDescription></ns:subResponse><ns:subResponse><responseCode xmlns="http://beans.oms.ecom.ecc.com/xsd">1147</responseCode><responseDescription xmlns="http://beans.oms.ecom.ecc.com/xsd">Order Grand Total and sum of OrderItem Grand Total mismatch</responseDescription></ns:subResponse><ns:transactionNumber>0717299145</ns:transactionNumber></ns:return></ns:createOrderResponse>
期望的输出:
<ns:createOrderResponse xmlns:ns="http://services.oms.ecom.ecc.com"><ns:return type="com.ecc.ecom.oms.beans.xsd.CreateOrderResponse"><ns:omsGeneratedOrderId xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" /><ns:responseCode>99</ns:responseCode><ns:responseDesc>INVALID ORDER</ns:responseDesc><ns:sellerSiteId>10196</ns:sellerSiteId><ns:serverProcElapsedTime>8</ns:serverProcElapsedTime><ns:siteGeneratedOrderId xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" /><ns:subResponse><responseCode xmlns="http://services.oms.ecom.ecc.com">1144</responseCode><responseDescription xmlns="http://services.oms.ecom.ecc.com">Order Total mismatch</responseDescription></ns:subResponse><ns:subResponse><responseCode xmlns="http://services.oms.ecom.ecc.com">1147</responseCode><responseDescription xmlns="http://services.oms.ecom.ecc.com">Order Grand Total and sum of OrderItem Grand Total mismatch</responseDescription></ns:subResponse><ns:transactionNumber>0717299145</ns:transactionNumber></ns:return></ns:createOrderResponse>
基本上我想替换:
命名空间:http://beans.oms.ecom.shc.com/xsd 从 命名空间:http://services.oms.ecom.ecc.com
答案 0 :(得分:0)
CAVEAT:以下是未经测试但展示了这些想法。
如果您知道要期望哪些特定元素和属性,则相对容易 - 它与任何其他元素和属性相同“当您看到此元素时,输出此其他元素而不是”模板,递归以覆盖整个文档。从身份样式表开始,添加表单的相应模板:
<xsl:template match="wrongnamespace:fred"
xmlns:wrongnamespace="http://services.oms.ecom.ecc.com">
<rightnamespace:fred xmlns:rightnamespace="http://beans.oms.ecom.shc.com/xsd">
<xsl:apply-templates/>
</rightnamespace:fred>
</xsl:template>
和(对于属性)
<xsl:template match="@wrongnamespace:george"
xmlns:wrongnamespace="http://services.oms.ecom.ecc.com">
<xsl:attribute name="ns:george" value="."
namespace="http://beans.oms.ecom.shc.com/xsd"/>
</xsl:template>
......等等。
如果你不知道期望什么元素或属性,这就变得更加丑陋。在XSLT 1.0和XPath 1.0中,没有简单的方法可以说“任何元素节点”(尽管我认为这些在这些规范的2.0版本中得到了修复)。坚持使用1.0因为它得到了更广泛的支持,最简单的解决方案是使用优先级:拥有一个捕获属性的优先级较高的模板,然后使用另一个处理其他命名空间节点的模板(因此它们就是元素)。
<xsl:template match="@*[namespace-uri(.)="http://services.oms.ecom.ecc.com"
priority="1">
<xsl:attribute name="concat('ns:',localname(.))" value="."
namespace="http://beans.oms.ecom.shc.com/xsd"/>
</xsl:template>
<xsl:template match="node()[namespace-uri(.)="http://services.oms.ecom.ecc.com"
priority="1">
<xsl:element name="concat('ns:',localname(.))"
namespace="http://beans.oms.ecom.shc.com/xsd">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
再次,将这些添加到规范标识样式表将满足您的需求;它会捕捉并改变这两种情况,同时复制其他所有内容。
CAVEAT:这不会改变出现在字符串中的URIS。您可以添加一个模板,该模板查找包含旧URI的text()节点并输出新的URI;我将这作为读者的练习。
CAVEAT:这不会改变NAMESPACE NODES。您最终可能会使用旧前缀和命名空间的剩余声明。可以添加另一个模板来清理它;这也是留给读者的练习。
这应该足以让你开始。玩得开心。在XSLT中编程确实需要学习思考规则和替换而不是程序,但是当你习惯它时,它可以是一个非常富有表现力的工具。
(标准插件:如果你想要一个现成的测试解决方案,你可以在Dave Pawson的XSL FAQ网站上找到一个。如果在XSLT中工作,你真的需要注意这个资源;它会节省你做了很多工作,它有一些非常聪明且非常明显的解决方案。)