如何使用 XSLT 正确删除 XML 标记

Posted

技术标签:

【中文标题】如何使用 XSLT 正确删除 XML 标记【英文标题】:How to properly remove an XML tag using XSLT 【发布时间】:2021-09-17 01:43:04 【问题描述】:

我有一个如下的 XML 文档

<?xml version='1.0' encoding='UTF-8'?>
<STA_ORDERS>
 <STA_ORDER_LINES>
  <STA_ORDER_LINE>
   <ADDITIONAL_COST_AMOUNT>0.0</ADDITIONAL_COST_AMOUNT>
   <BRAND_NAME>Test</BRAND_NAME>
   <BUY_QUANTITY_DUE>2.0</BUY_QUANTITY_DUE>
   <BUY_UNIT_MEASURE>PCE</BUY_UNIT_MEASURE>
   <CARD_PRICE_SE>0.0</CARD_PRICE_SE>
   <CONV_FACTOR>1</CONV_FACTOR>
   <CURRENCY_CODE>SEK</CURRENCY_CODE>
   <CURRENCY_RATE>1.0</CURRENCY_RATE>
   <CUSTOMER_UNIT_MEASURE>pcs</CUSTOMER_UNIT_MEASURE>
   <DISCOUNT>0.0</DISCOUNT>
   <ORDER_LINE_NO>1</ORDER_LINE_NO>
   <PART_DESCRIPTION>SHEENA JKT OLIVE L</PART_DESCRIPTION>
   <PART_NO>010008002010</PART_NO>
   <PLANNED_DELIVERY_DATE>2021-07-02</PLANNED_DELIVERY_DATE>
   <PREFERRED_RETAIL_PRICE_SE>0.0</PREFERRED_RETAIL_PRICE_SE>
   <PRICE_CONVERSION_FACTOR>1</PRICE_CONVERSION_FACTOR>
   <PRICE_UNIT_MEASURE>pcs</PRICE_UNIT_MEASURE>
   <RELEASE_NO>3</RELEASE_NO>
   <SHIPMENT_PARTIAL>CP</SHIPMENT_PARTIAL>
   <UNIT_PRICE_IN_OUR_CURRENCY>1073.4</UNIT_PRICE_IN_OUR_CURRENCY>
   <UNIT_PRICE_IN_SUPPLIER_CURRENCY>1073.4</UNIT_PRICE_IN_SUPPLIER_CURRENCY>
   <VENDOR_PART_NO>010008002010</VENDOR_PART_NO>
  </STA_ORDER_LINE>
 </STA_ORDER_LINES>
</STA_ORDERS>

我需要一个 XSL 文档来传输上述 xml,以便如果版本号只有一个数字, 将有一个前导零。

示例 3 => 03, 2 => 02, 10 => 10(10 已经有 2 个数字,所以我们保持原样)

我用过下面的xsl。

<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet xmlns:ifs="urn:ifsworld-com:schemas:TYPE_SCHEMA_NAME_HERE" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" version="1.0" exclude-result-prefixes="ifs date">
<xsl:output method="xml" indent="yes"/>

   <xsl:template match="STA_ORDER_LINE">
     <xsl:choose>
        <xsl:when test="(RELEASE_NO > 9)">
           <xsl:apply-templates select="@*|node()" />
        </xsl:when>
        <xsl:otherwise>
           <xsl:apply-templates select="@*|node()" />
           <RELEASE_NO>
             <xsl:value-of select="concat('0',RELEASE_NO)"/>
           </RELEASE_NO>
        </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

</xsl:stylesheet>

但似乎无法正常工作,因为它添加了带有更正的新标签,但旧标签似乎仍然可用。 (https://www.freeformatter.com/xsl-transformer.html)

有什么想法吗??

=================================

修订后的 XML 似乎不起作用。我已将 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:ifsworld-com:schemas:outbound_distribution_transactions_sta_send_purchase_order_sta_request" 添加到 标记。知道为什么它不起作用吗??

<?xml version='1.0' encoding='UTF-8'?>
<STA_ORDERS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:ifsworld-com:schemas:outbound_distribution_transactions_sta_send_purchase_order_sta_request">
 <ACTIONTYPE>CREATE</ACTIONTYPE>
 <BUYER>IFS APPLICATIONS</BUYER>
 <COUNTRY_CODE>SE</COUNTRY_CODE>
 <CURRENCY_CODE>SEK</CURRENCY_CODE>
 <CUSTOMER_COMPANY_COUNTRY>SVERIGE</CUSTOMER_COMPANY_COUNTRY>
 <CUSTOMER_COMPANY_NAME>Stadium Sverige AB</CUSTOMER_COMPANY_NAME>
 <CUSTOMER_POSTAL_ADDRESS>Norra Promenaden,,602 22 Norrköping,,SVERIGE</CUSTOMER_POSTAL_ADDRESS>
 <DELIVERY_TERMS_CODE>DPC</DELIVERY_TERMS_CODE>
 <DELIVERY_TERMS_DESCRIPTION>023 DDP Norrköping CWH</DELIVERY_TERMS_DESCRIPTION>
 <EAN_LOCATION_DELIVERY_ADDRESS>7350031681995</EAN_LOCATION_DELIVERY_ADDRESS>
 <EAN_SUPPLIER_DOCUMENT_ADDRESS>EMCAT1</EAN_SUPPLIER_DOCUMENT_ADDRESS>
 <FUNCTION_CODE>4</FUNCTION_CODE>
 <ORDER_DATE>2021-07-02</ORDER_DATE>
 <ORDER_NO>949</ORDER_NO>
 <ORDER_REVISION>0</ORDER_REVISION>
 <PAY_TERM_DAYS> Da</PAY_TERM_DAYS>
 <PAY_TERM_DESCRIPTION>20 Days Net</PAY_TERM_DESCRIPTION>
 <PAY_TERM_PERIOD>D</PAY_TERM_PERIOD>
 <PAY_TERM_REFERENCE>e</PAY_TERM_REFERENCE>
 <RECEIVER_COMMUNICATION_ID>CONNECT</RECEIVER_COMMUNICATION_ID>
 <SENDER_COMMUNICATION_ID>S17647</SENDER_COMMUNICATION_ID>
 <SHIP_VIA_DESCRIPTION>Car</SHIP_VIA_DESCRIPTION>
 <SUPPLIER_ADDRESS_NO>1</SUPPLIER_ADDRESS_NO>
 <TAXATION_NO>SE556236439701</TAXATION_NO>
 <VENDOR_NO>90054</VENDOR_NO>
 <WANTED_DELIVERY_DATE>2021-07-02</WANTED_DELIVERY_DATE>
 <DEPARTMENT_ID>33</DEPARTMENT_ID>
 <CHANGE>SENT</CHANGE>
 <STA_DELIVER_TO>
  <STA_ORDER_ADDRESS>
   <ADDRESS_1>Ströbogatan 5</ADDRESS_1>
   <CITY>NORRKÖPING</CITY>
   <COUNTRY>SVERIGE</COUNTRY>
   <RECEIVER_NAME>DC Stadium</RECEIVER_NAME>
   <ZIP_CODE>602 23</ZIP_CODE>
  </STA_ORDER_ADDRESS>
 </STA_DELIVER_TO>
 <STA_ORDER_LINES>
  <STA_ORDER_LINE>
   <ADDITIONAL_COST_AMOUNT>0.0</ADDITIONAL_COST_AMOUNT>
   <BRAND_NAME>Test</BRAND_NAME>
   <BUY_QUANTITY_DUE>2.0</BUY_QUANTITY_DUE>
   <BUY_UNIT_MEASURE>PCE</BUY_UNIT_MEASURE>
   <CARD_PRICE_SE>0.0</CARD_PRICE_SE>
   <CONV_FACTOR>1</CONV_FACTOR>
   <CURRENCY_CODE>SEK</CURRENCY_CODE>
   <CURRENCY_RATE>1.0</CURRENCY_RATE>
   <CUSTOMER_UNIT_MEASURE>pcs</CUSTOMER_UNIT_MEASURE>
   <DISCOUNT>0.0</DISCOUNT>
   <ORDER_LINE_NO>1</ORDER_LINE_NO>
   <PART_DESCRIPTION>SHEENA JKT OLIVE L</PART_DESCRIPTION>
   <PART_NO>010008002010</PART_NO>
   <PLANNED_DELIVERY_DATE>2021-07-02</PLANNED_DELIVERY_DATE>
   <PREFERRED_RETAIL_PRICE_SE>0.0</PREFERRED_RETAIL_PRICE_SE>
   <PRICE_CONVERSION_FACTOR>1</PRICE_CONVERSION_FACTOR>
   <PRICE_UNIT_MEASURE>pcs</PRICE_UNIT_MEASURE>
   <RELEASE_NO>1</RELEASE_NO>
   <SHIPMENT_PARTIAL>CP</SHIPMENT_PARTIAL>
   <UNIT_PRICE_IN_OUR_CURRENCY>1073.4</UNIT_PRICE_IN_OUR_CURRENCY>
   <UNIT_PRICE_IN_SUPPLIER_CURRENCY>1073.4</UNIT_PRICE_IN_SUPPLIER_CURRENCY>
   <VENDOR_PART_NO>010008002010</VENDOR_PART_NO>
  </STA_ORDER_LINE>
  <STA_ORDER_LINE>
   <ADDITIONAL_COST_AMOUNT>0.0</ADDITIONAL_COST_AMOUNT>
   <BRAND_NAME>Test</BRAND_NAME>
   <BUY_QUANTITY_DUE>2.0</BUY_QUANTITY_DUE>
   <BUY_UNIT_MEASURE>PCE</BUY_UNIT_MEASURE>
   <CARD_PRICE_SE>0.0</CARD_PRICE_SE>
   <CONV_FACTOR>1</CONV_FACTOR>
   <CURRENCY_CODE>SEK</CURRENCY_CODE>
   <CURRENCY_RATE>1.0</CURRENCY_RATE>
   <CUSTOMER_UNIT_MEASURE>pcs</CUSTOMER_UNIT_MEASURE>
   <DISCOUNT>0.0</DISCOUNT>
   <ORDER_LINE_NO>1</ORDER_LINE_NO>
   <PART_DESCRIPTION>SHEENA JKT OLIVE L</PART_DESCRIPTION>
   <PART_NO>010008002010</PART_NO>
   <PLANNED_DELIVERY_DATE>2021-07-02</PLANNED_DELIVERY_DATE>
   <PREFERRED_RETAIL_PRICE_SE>0.0</PREFERRED_RETAIL_PRICE_SE>
   <PRICE_CONVERSION_FACTOR>1</PRICE_CONVERSION_FACTOR>
   <PRICE_UNIT_MEASURE>pcs</PRICE_UNIT_MEASURE>
   <RELEASE_NO>2</RELEASE_NO>
   <SHIPMENT_PARTIAL>CP</SHIPMENT_PARTIAL>
   <UNIT_PRICE_IN_OUR_CURRENCY>1073.4</UNIT_PRICE_IN_OUR_CURRENCY>
   <UNIT_PRICE_IN_SUPPLIER_CURRENCY>1073.4</UNIT_PRICE_IN_SUPPLIER_CURRENCY>
   <VENDOR_PART_NO>010008002010</VENDOR_PART_NO>
  </STA_ORDER_LINE>
  <STA_ORDER_LINE>
   <ADDITIONAL_COST_AMOUNT>0.0</ADDITIONAL_COST_AMOUNT>
   <BRAND_NAME>Test</BRAND_NAME>
   <BUY_QUANTITY_DUE>1.0</BUY_QUANTITY_DUE>
   <BUY_UNIT_MEASURE>PCE</BUY_UNIT_MEASURE>
   <CARD_PRICE_SE>0.0</CARD_PRICE_SE>
   <CONV_FACTOR>1</CONV_FACTOR>
   <CURRENCY_CODE>SEK</CURRENCY_CODE>
   <CURRENCY_RATE>1.0</CURRENCY_RATE>
   <CUSTOMER_UNIT_MEASURE>pcs</CUSTOMER_UNIT_MEASURE>
   <DISCOUNT>0.0</DISCOUNT>
   <ORDER_LINE_NO>1</ORDER_LINE_NO>
   <PART_DESCRIPTION>SHEENA JKT OLIVE L</PART_DESCRIPTION>
   <PART_NO>010008002010</PART_NO>
   <PLANNED_DELIVERY_DATE>2021-07-02</PLANNED_DELIVERY_DATE>
   <PREFERRED_RETAIL_PRICE_SE>0.0</PREFERRED_RETAIL_PRICE_SE>
   <PRICE_CONVERSION_FACTOR>1</PRICE_CONVERSION_FACTOR>
   <PRICE_UNIT_MEASURE>pcs</PRICE_UNIT_MEASURE>
   <RELEASE_NO>3</RELEASE_NO>
   <SHIPMENT_PARTIAL>CP</SHIPMENT_PARTIAL>
   <UNIT_PRICE_IN_OUR_CURRENCY>1073.4</UNIT_PRICE_IN_OUR_CURRENCY>
   <UNIT_PRICE_IN_SUPPLIER_CURRENCY>1073.4</UNIT_PRICE_IN_SUPPLIER_CURRENCY>
   <VENDOR_PART_NO>010008002010</VENDOR_PART_NO>
  </STA_ORDER_LINE>
 </STA_ORDER_LINES>
</STA_ORDERS>

【问题讨论】:

【参考方案1】:

以下对我有用:

<xsl:choose>
        <xsl:when test='/STA_ORDERS/STA_ORDER_LINES/STA_ORDER_LINE/RELEASE_NO &gt; 9'>
          <RELEASE_NO>
            <xsl:value-of select="/STA_ORDERS/STA_ORDER_LINES/STA_ORDER_LINE/RELEASE_NO"/>
          </RELEASE_NO>
        </xsl:when>
        <xsl:otherwise>
          <RELEASE_NO>
            <xsl:value-of select="concat('0',/STA_ORDERS/STA_ORDER_LINES/STA_ORDER_LINE/RELEASE_NO)"/>
          </RELEASE_NO>
        </xsl:otherwise>
      </xsl:choose>

【讨论】:

【参考方案2】:

请尝试以下 XSLT。

它考虑了一个默认命名空间。

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:ifsworld-com:schemas:outbound_distribution_transactions_sta_send_purchase_order_sta_request">
    <xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="no"/>
    <xsl:strip-space elements="*"/>
  
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ns1:RELEASE_NO[string-length() = 1]">
        <xsl:copy>
            <xsl:value-of select="concat('0', .)"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

【讨论】:

非常感谢。它完美地工作。你确实是一个救生员:D 修订后的 XML 似乎不起作用。我只在 xmlns:xsi="w3.org/2001/XMLSchema-instance" xmlns="urn:ifsworld-com:schemas:outbound_distribution_transactions_sta_send_purchase_order_sta_request" 下面添加到 标签。知道为什么它不起作用吗?? @ShankaSomasiri,我更新了答案以考虑添加的命名空间。永远不要在 XML 文档中省略命名空间。 谢谢。我会记住这一点。我对 XSL 有点陌生,非常感谢您的帮助【参考方案3】:

它失败了,因为您要处理内容两次,一次使用 xsl:value of,一次使用 apply-templates

   <xsl:apply-templates select="@*|node()" />
   <RELEASE_NO>
     <xsl:value-of select="concat('0',RELEASE_NO)"/>
   </RELEASE_NO>

但是有很多更简洁的方法可以做到这一点。伊扎克给你看了一个;另一个是使用format-number(RELEASE_NO, '00');另一种(相当偷偷摸摸的)方式是substring(string(RELEASE_NO + 100)), 2)

【讨论】:

谢谢迈克尔。对修订后的 XML 的任何想法似乎都不起作用。 如果您有新问题,请将其作为新问题提出,而不是作为对先前问题的修改。当您这样做时,任何人都无法将问题和答案联系起来。另外,请不要告诉我们某事“不起作用”而不告诉我们它是如何失败的——据我们所知,它产生了正确的答案,但您的期望是错误的。 注意到@MichaelKay。谢谢

以上是关于如何使用 XSLT 正确删除 XML 标记的主要内容,如果未能解决你的问题,请参考以下文章

使用 XSLT 删除重复标记及其在 XML 中的子项

如何使用 XSLT 在 xml 文件中查找元素并将其放置在另一个标记中?

如何使用 XSLT 从 XML 中删除名称空间

如何使用 XSLT 从 XML 中删除货币符号?

XSLT:如何解析嵌入在 XML 标记中的 HTML

如何使用带有样式表和 xsltproc 的 xslt 从 xml 中删除元素?