如果标签不存在,使用 XSLT 将 XML 标签添加到 SOAP 消息

add XML tag to SOAP message with XSLT if tag doesn't exist

我对 XSLT 很陌生,不知道如何为我想要的转换找到解决方案。 我们收到一个 SOAP 请求,需要检查某个标记(步骤)是否存在。如果不存在,我想将其添加到 SOAP 消息中。

我们是 运行 Azure 上的接口 API 管理,仅在 1.0 版中允许 XSLT。

XML 例子

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
   <ProductionToSupply xmlns="http://somenamespace.com">
      <ProductionDataList>
         <ProductionData>
            <Material_Number>5</Material_Number>
            <Doc_Number>1234</Doc_Number>
            <Description>abcde</Description>
         </ProductionData>
      </ProductionDataList>
   </ProductionToSupply>
</soap:Body>
</soap:Envelope>

XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"  
xmlns:ns1="http://somenamespace.com" exclude-result-prefixes="ns1">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="soap:Envelope/soap:Body/ns1:ProductionToSupply/ns1:ProductionDataList/ns1:ProductionData/ns1:Doc_Number">
<xsl:if test="not(soap:Envelope/soap:Body/ns1:ProductionToSupply/ns1:ProductionDataList/ns1:ProductionData/ns1:Steps)">
    <Steps xmlns="http://somenamespace.com">NA</Steps>
</xsl:if>
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>


</xsl:stylesheet>

期望输出

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
   <ProductionToSupply xmlns="http://somenamespace.com">
      <ProductionDataList>
         <ProductionData>
            <Material_Number>5</Material_Number>
            <Doc_Number>1234</Doc_Number>
            <Description>abcde</Description>
            <Steps>NA</Steps>
         </ProductionData>
      </ProductionDataList>
   </ProductionToSupply>
</soap:Body>
</soap:Envelope>

如果标签 "Steps" 不在组 "ProductionData" 中,预期的结果是只添加它,但我不知道如何设置适当的匹配模式。

在此先感谢您的帮助 蒂姆

如果您只想匹配没有 Steps 元素的组 ProductionData,则模板匹配将是这个

 <xsl:template match="ns1:ProductionData[not(ns1:Steps)]">

然后您可以复制 ProductionData 元素及其 child 节点,并同时插入 Steps 元素

试试这个 XSLT

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"  
xmlns:ns1="http://somenamespace.com" exclude-result-prefixes="ns1">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="ns1:ProductionData[not(ns1:Steps)]">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
    <Steps xmlns="http://somenamespace.com">NA</Steps>
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

这会将 Steps 添加为最后一个 child。如果你想在 Doc_Number 之后立即使用它,请用这个

替换模板
<xsl:template match="ns1:ProductionData[not(ns1:Steps)]/ns1:Doc_Number">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
  <Steps xmlns="http://somenamespace.com">NA</Steps>
</xsl:template>