xml - 通过匹配 XML 标签来复制内容
问题描述
我想通过匹配特定节点来复制 XML 的所有内容,并为每个重复的“postItemCost”节点添加一个 SOAP 信封。
源 XML:
<ns1:postItemCost xmlns:ns1="http://items.test.com/">
<ItemInvCostReqList>
<ItemInvCostRequest>
<invcost>
<avgcost>0.00</avgcost>
<lastcost>0.00</lastcost>
<stdcost>0.00</stdcost>
</invcost>
<location>2201</location>
</ItemInvCostRequest>
<itemnum>9322979</itemnum>
</ItemInvCostReqList>
</ns1:postItemCost>
<ns1:postItemCost xmlns:ns1="http://items.test.com/">
<ItemInvCostReqList>
<ItemInvCostRequest>
<invcost>
<avgcost>0.00</avgcost>
<lastcost>0.00</lastcost>
<stdcost>0.00</stdcost>
</invcost>
<location>1101</location>
</ItemInvCostRequest>
<itemnum>9322979</itemnum>
</ItemInvCostReqList>
</ns1:postItemCost>
<ns1:postItemCost xmlns:ns1="http://items.test.com/">
<ItemInvCostReqList>
<ItemInvCostRequest>
<invcost>
<avgcost>1000.00</avgcost>
<lastcost>1000.00</lastcost>
<stdcost>1000.00</stdcost>
</invcost>
<location>1101</location>
</ItemInvCostRequest>
<itemnum>9322984</itemnum>
</ItemInvCostReqList>
</ns1:postItemCost>
</ns0:Message1>
</ns0:Messages>
预期产出 -
<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
<ns0:Message1>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ns1:postItemCost xmlns:ns1="http://items.test.com/">
<ItemInvCostReqList>
<ItemInvCostRequest>
<invcost>
<avgcost>0.00</avgcost>
<lastcost>0.00</lastcost>
<stdcost>0.00</stdcost>
</invcost>
<location>2201</location>
</ItemInvCostRequest>
<itemnum>9322979</itemnum>
</ItemInvCostReqList>
</ns1:postItemCost>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ns1:postItemCost xmlns:ns1="http://items.test.com/">
<ItemInvCostReqList>
<ItemInvCostRequest>
<invcost>
<avgcost>0.00</avgcost>
<lastcost>0.00</lastcost>
<stdcost>0.00</stdcost>
</invcost>
<location>1101</location>
</ItemInvCostRequest>
<itemnum>9322979</itemnum>
</ItemInvCostReqList>
</ns1:postItemCost>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ns1:postItemCost xmlns:ns1="http://items.test.com/">
<ItemInvCostReqList>
<ItemInvCostRequest>
<invcost>
<avgcost>1000.00</avgcost>
<lastcost>1000.00</lastcost>
<stdcost>1000.00</stdcost>
</invcost>
<location>1101</location>
</ItemInvCostRequest>
<itemnum>9322984</itemnum>
</ItemInvCostReqList>
</ns1:postItemCost>
</soapenv:Body>
</soapenv:Envelope>
这是我的 XSLT:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="w3.org/1999/XSL/Transform" xmlns:ns0="sap.com/xi/XI/SplitAndMerge" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no" omit-xml-declaration="yes"/>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv="schemas.xmlsoap.org/soap/envelope">
<soapenv:Header/>
<soapenv:Body>
<xsl:template match="Message//Message1//postInvCostRequest">
<xsl:copy-of select="/postInvCostRequest"/>
</xsl:template>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
</xsl:stylesheet>
我想为每个重复的“postItemCost”节点添加 SOAP 信封。
那么,您能否帮助我提供可以帮助我实现预期输出的 XSLT 代码。
解决方案
试试这个方法?
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge"
xmlns:ns1="http://items.test.com/">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/ns0:Messages">
<xsl:copy>
<ns0:Message1>
<xsl:for-each select="ns0:Message1/ns1:postItemCost">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<xsl:copy-of select="."/>
</soapenv:Body>
</soapenv:Envelope>
</xsl:for-each>
</ns0:Message1>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
演示:http: //xsltransform.net/jxWYjVU
添加:
如评论中所述,您无法控制名称空间声明的出现位置。以下技巧将适用于某些处理器并强制xmlns:ns1="http://items.test.com/"
声明出现在 ns1:postItemCost
元素上 - 但不能保证它适用于处理链的每个处理器或序列化组件:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge"
xmlns:ns3="http://items.test.com/"
exclude-result-prefixes="ns3">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/ns0:Messages">
<xsl:copy>
<ns0:Message1>
<xsl:for-each select="ns0:Message1/ns3:postItemCost">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<xsl:copy-of select="."/>
</soapenv:Body>
</soapenv:Envelope>
</xsl:for-each>
</ns0:Message1>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
推荐阅读
- laravel - Laravel Vue SPA 项目不安全的中间件 localstorage
- html - 动态不渲染数据
我正在尝试创建一个动态表,该表根据以下格式呈现插入的数据
{headers: ["header1", "header2"], rows: [["data1", "data2"], ["moredata", "wowoso muchdata"]]}
Rows 只是一个数组数组,每个数组都是表中的一行。
我将这些数据传递给呈现表格的 React 组件。代码如下:
- java - 闲置 30 秒后关闭灯
- html - Safari 有时不会水平居中文本
- powershell - 将每个子目录的内容移动到文件夹
- django - 如何从弹出模式引导程序中的链接运行函数
- c# - 很难理解级联删除的工作原理以及如何配置关系
- c# - 如何知道一个小时的文件夹中是否没有新文件
- batch-file - 尝试批量制作“操作系统”
- visual-studio - 在 Visual Studio 2019 中调试时 Dockerfile 似乎没有运行