我有以下XML用于Web服务的批处理,它只执行基本的算术运算。在处理期间,一些节点将失败,例如,由于非法参数,例如导致除零的那些(在示例中为第三节点)。我需要创建一个单独的XML文档来连接这些违规节点,或者由于某些其他原因而失败的节点。我无法想出一个合适的XPATH方法来连接XML片段。
源XML:
<Envelopes>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fc="http://fc.org/">
<soapenv:Header/>
<soapenv:Body>
<fc:add>
<arg0>99938</arg0>
<arg1>62</arg1>
</fc:add>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fc="http://fc.org/">
<soapenv:Header/>
<soapenv:Body>
<fc:addaaaaaaaaaa>
<arg0>34</arg0>
<arg1>223</arg1>
</fc:addaaaaaaaaaa>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fc="http://fc.org/">
<soapenv:Header/>
<soapenv:Body>
<fc:divide>
<arg0>634</arg0>
<arg1>0</arg1>
</fc:divide>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fc="http://fc.org/">
<soapenv:Header/>
<soapenv:Body>
<fc:subtract>
<arg0>3400</arg0>
<arg1>2200</arg1>
</fc:subtract>
</soapenv:Body>
</soapenv:Envelope>
</Envelopes>
XSL转换
<xsl:stylesheet version=
"1.0" xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform" xmlns:dp=xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:str="http://exslt.org/strings">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:for-each select="/Envelopes/soapenv:Envelope">
<!-- introduce a variable for the current envelope -->
<xsl:variable name="fc" select="."/>
<!-- I NEED TO CONCAT THE ENTIRE NODE TO CREATE A BRAND NEW XML FILE -->
<xsl:variable name="addEnvelope" select="'<Envelopes>',."/>
<xsl:message terminate="no" dp:priority="notice">
<xsl:copy-of select="$addEnvelope"/>
</xsl:message>
<!-- I SEE THE OUTPUT <Envelopes>324 0 etc... WHAT I WANT IS TO GET AN OUTPUT LIKE: -->
<Envelopes><soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:fc="http://fc.org/">
<soapenv:Header/>
<soapenv:Body>
<fc:multiply>
<arg0>34</arg0>
<arg1>2</arg1>
</fc:multiply>
</soapenv:Body>
</soapenv:Envelope> etc...
</xsl:for-each>
答案 0 :(得分:1)
由于问题有点模糊,很难给出确切的答案,但我建议你需要建立在XSLT identity transform之上。
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
在XSLT中,您不会“连接”节点,这是您对字符串执行的操作,但您可以将元素复制或创建新元素到输出树。上面的标识模板本身将文档中的所有节点复制到输出树。通过这样做,这意味着您真正需要做的就是添加模板来处理您想要更改的节点,或者在您的情况下,添加模板以停止复制节点。
例如,你提到了除零。假设您要创建仅包含 arg1 为零的包络元素的XML。这意味着,当与XSLT标识模板一起使用时,您只需要一个模板来忽略包络元素,其中 arg1 不为零。
<xsl:template match="soapenv:Envelope[not(soapenv:Body/fc:divide/arg1 = '0')]" />
就是这样!试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:fc="http://fc.org/">
<xsl:output method="yes" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="soapenv:Envelope[not(soapenv:Body/fc:divide/arg1 = '0')]" />
</xsl:stylesheet>
或者,如果您希望明确选择要复制的信封元素,而不是要复制,则可以创建一个模板以匹配信封元素,然后使用 xsl:apply-templates 选择您想要的。
此XSLT也应该起作用
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:fc="http://fc.org/">
<xsl:output method="yes" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Envelopes">
<xsl:apply-templates select="soapenv:Envelope[soapenv:Body/fc:divide/arg1 = '0']" />
</xsl:template>
</xsl:stylesheet>