使用Regex ABAP删除XML中的空标签

问题描述

我在生成XML时遇到问题。我使用了简单转换。 XML中的许多标签都是空的。我找到了可以使用Regex摆脱这些标签的信息,但它并不完美。让我告诉你它的外观。

不使用正则表达式:

 <?xml version="1.0" encoding="utf-8" ?> 
<Invoice 
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" 
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" 
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
     <cbc:DueDate /> 
     <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode> 
     <cbc:Note /> 
     <cbc:DocumentCurrencyCode>PLN</cbc:DocumentCurrencyCode> 
     <cbc:TaxCurrencyCode /> 
     <cbc:BuyerReference /> 
     <cac:InvoicePeriod>
      <cbc:StartDate /> 
      <cbc:EndDate /> 
      <cbc:DescriptionCode /> 
     </cac:InvoicePeriod>

用ABAP编写的正则表达式:

      REPLACE ALL OCCURRENCES OF REGEX
    '(<!\[CDATA\[([^]]|(\][^]])|(\]\][^>]))*\]\]>)|(<([^?][^><\s]*)(\s[^><]+)?/>)'
      IN exportxml
      WITH '$1'.

使用正则表达式后:

      <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode> 
      <cbc:DocumentCurrencyCode>PLN</cbc:DocumentCurrencyCode> 
      <cac:InvoicePeriod />

SimpleTransformation看起来像这样:

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates" xmlns:ddic="http://www.sap.com/abapxml/types/dictionary" xmlns:def="http://www.sap.com/abapxml/types/defined">
  <tt:root name="ZXT_INVOICE" type="ddic:ZXT_INVOICE"/>
  <tt:template>
    <Invoice
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:ccts="urn:un:unece:uncefact:documentation:2" 
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
>
      <cbc:DueDate tt:value-ref=".ZXT_INVOICE.DUEDATE"/>
      <cbc:InvoiceTypeCode tt:value-ref=".ZXT_INVOICE.INVOICETYPECODE"/>
      <cbc:Note tt:value-ref=".ZXT_INVOICE.NOTE"/>
      <cbc:DocumentCurrencyCode tt:value-ref=".ZXT_INVOICE.DOCUMENTCURRENCYCODE"/>
      <cbc:TaxCurrencyCode tt:value-ref=".ZXT_INVOICE.TAXCURRENCYCODE"/>
      <cbc:AccountingCost tt:value-ref=".ZXT_INVOICE.ACCOUNTINGCOST"/>
      <cbc:BuyerReference tt:value-ref=".ZXT_INVOICE.BUYERREFERENCE"/>
      <cac:InvoicePeriod>
        <cbc:StartDate tt:value-ref=".ZXT_INVOICE.INVOICE_PERIOD.STARTDATE"/>
        <cbc:EndDate tt:value-ref=".ZXT_INVOICE.INVOICE_PERIOD.ENDDATE"/>
        <cbc:DescriptionCode tt:value-ref=".ZXT_INVOICE.INVOICE_PERIOD.DESCRIPTIONCODE"/>
      </cac:InvoicePeriod>
    </Invoice>
  </tt:template>
</tt:transform>

Regex删除了简单元素,但是像<cac:InvoicePeriod>这样的嵌套元素存在问题。在我的程序中,我有许多嵌套元素。 您能帮我修改正则表达式或找到其他解决方案吗?

感谢您的帮助。

解决方法

您的ABAP正则表达式文字:

(<!\[CDATA\[([^]]|(\][^]])|(\]\][^>]))*\]\]>)|(<([^?][^><\s]*)(\s[^><]+)?/>)

可以通过以下方式进行纠正和简化:

(<!\[CDATA\[(?!\]\]>).*\]\]>)|<[^?!](?:(?!>|\/>).)*\/>

注意:(?!xyz).是否定预览条件,表示任何字符(.),只要它不是x后跟yz即可。

,

使用XSLT递归删除空的xml元素 解决方案:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*[descendant::text() or descendant-or-self::*/@*[string()]]">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="@*[string()]">
    <xsl:copy/>
</xsl:template>

</xsl:stylesheet>

参考链接: 1 2

对我来说效果很好。感谢您的帮助。