XSLT,将一些带有前缀的标签从 lt/gt 更改为 <>,而一些仍然使用 lt/gt 的标签

  • 本文关键字:标签 XSLT 前缀 xml xslt
  • 更新时间 :
  • 英文 :


也许有人帮我决定一项任务:(我输入了xml,例如:

<n0:sendRequests xmlns:n0="http://upg.sbns.bssys.com/" xmlns:prx="urn:sap.com:proxy:DAX:/1SAI/TAS530E8C549ADDED8C7693:740">
<n0:requests>&lt;upg:Request xmlns:upg="http://bssys.com/upg/request" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" requestId="55555555-5555-5555-5555-550000090095" version="1" sender="1" receiver="1"&gt;&lt;upg:Models&gt;&lt;upg:Model&gt;&lt;StatementRequest xmlns="http://bssys.com/sbns/integration"&gt;&lt;docId&gt;90095&lt;/docId&gt;&lt;docDate&gt;2020-09-10&lt;/docDate&gt;&lt;docNumber&gt;90095&lt;/docNumber&gt;&lt;orgId&gt;6c74b51b-fb90-4270-8a1b-ae07177a8905&lt;/orgId&gt;&lt;orgInn&gt;7736050003&lt;/orgInn&gt;&lt;orgName&gt;JSC Company&lt;/orgName&gt;&lt;fromDate&gt;2020-05-11&lt;/fromDate&gt;&lt;toDate&gt;2020-05-11&lt;/toDate&gt;&lt;accounts&gt; &lt;Acc&gt;&lt;account&gt;40702810500010000848&lt;/account&gt;&lt;bankBIC&gt;044525220&lt;/bankBIC&gt;&lt;bankName&gt;ABR&lt;/bankName&gt;&lt;orgName&gt;JSC Company&lt;/orgName&gt;&lt;/Acc&gt;&lt;/accounts&gt;&lt;signCollection&gt;&lt;SignCollection&gt;&lt;/SignCollection&gt;&lt;/signCollection&gt;&lt;/StatementRequest&gt;&lt;/upg:Model&gt;&lt;/upg:Models&gt;&lt;/upg:Request&gt;
</n0:requests>
<n0:sessionId>0174774e-e79f-19d8-bf28-5e423cf0d53c</n0:sessionId>
</n0:sendRequests>

我有xslt映射:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:upg="http://upg.sbns.bssys.com/" xmlns:n0="http://upg.sbns.bssys.com/">
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="n0:requests">
<xsl:copy>
<xsl:text disable-output-escaping="yes">&lt;![CDATA[ </xsl:text>
<xsl:value-of select="." disable-output-escaping="yes"/>
<xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>`

输出应该是:

<n0:sendRequests>
<n0:requests><![CDATA[
<upg:Request requestId="13131313-0000-1111-2211-001111111111" version="1" sender="1" 
receiver="1" xmlns:upg="http://bssys.com/upg/request" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<upg:Models>
<upg:Model>&lt;StatementRequest 
xmlns=&quot;http://bssys.com/sbns/integration&quot;&gt; 
&lt;orgId&gt;b14a6b8c-54ba-45af-8420-fdac775f6fe5&lt;/orgId&gt; 
&lt;accounts&gt; 
&lt;Acc&gt; 
&lt;account&gt;40702810200000005400&lt;/account&gt; 
&lt;bankBIC&gt;044030861&lt;/bankBIC&gt; 
&lt;/Acc&gt; 
&lt;/accounts&gt; 
&lt;docDate&gt;2020-09-08&lt;/docDate&gt; 
&lt;docId&gt;13131312-1fe4-11ea-9220-000c29bc93aa&lt;/docId&gt; 
&lt;docNumber&gt;133&lt;/docNumber&gt; 
&lt;fromDate&gt;2020-09-01&lt;/fromDate&gt; 
&lt;orgInn&gt;7810356897&lt;/orgInn&gt; 
&lt;orgName&gt;ЗАО  &quot;JSC Company&quot;&lt;/orgName&gt; 
&lt;toDate&gt;2020-09-02&lt;/toDate&gt; 
&lt;signCollection&gt;
&lt;SignCollection/&gt;
&lt;/signCollection&gt;
&lt;/StatementRequest&gt; 
</upg:Model>
</upg:Models>
</upg:Request>
]]></n0:requests>
<n0:sessionId>01746e15-004e-14f5-b4e6-f6c8b357e000</n0:sessionId>
</n0:sendRequests>

内部标记n0:请求需要替换&lt;gt到<gt;对于前缀为upg:和keep&lt;gt用于没有前缀的其他标记(例如<StatementRequest(。

现在我的xslt替换所有&lt;gt到<gt;:(这真的可以在XSLT上实现吗?

您的问题是什么还不清楚。您的样式表实际上什么都不做。转义的XML在语义上等同于CDATA部分中包含的XML。只需执行以下操作,您就可以更简单、更优雅地获得相同的结果:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:n0="http://upg.sbns.bssys.com/" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata-section-elements="n0:requests"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

您期望的输出显示了一个CDATA部分,其中包含一些正在转义的XML内容,这没有任何意义。

通常,当您有一个表示XML的字符串(无论是转义的还是CDATA中包含的(,并且您想更改该字符串的XML内容时,最好先将该字符串转换为XML,然后使用XSLT正常处理它。否则,您只能进行字符串操作,这非常乏味且容易出错。

您正在从输入和输出中的词法XML的角度讨论这个问题,但XSLT的观点是错误的:您需要考虑XSLT从解析器接收节点树,并将节点树传递给序列化程序。

请注意,您的示例输出包含

<upg:Model>&lt;StatementRequest 
xmlns=&quot;http://bssys.com/sbns/integration&quot;&gt;
...
&lt;/StatementRequest&gt; 
</upg:Model>

表示与完全相同的节点树

<upg:Model><![CDATA[<StatementRequest 
xmlns="http://bssys.com/sbns/integration">
...
</StatementRequest>]]>
</upg:Model>

这些只是同一结果树的不同序列化,所以就XSLT而言,它们是相同的。

使用现代XSLT处理器(XSLT3.0(,您可以使用以下构造来构造这样的结果:

<upg:Model>
<xsl:variable name="temp">
<StatementRequest 
xmlns="http://bssys.com/sbns/integration">
...
</StatementRequest>
</xsl:variable>
<xsl:value-of select="serialize($temp)"/>  
</upg:Model>

但是serialize((函数在早期的XSLT版本中不可用。

最新更新