如何用实际的消息类型名称替换根标记?

时间:2019-05-14 08:16:27

标签: xml xslt

对于XSLT代码,我想征询您的意见,我可以使用它用消息的实际名称(ns1)替换根标签。

“ Rechnungen”应替换为带有附加标题的实际消息类型名称。谢谢!

源XML:

<?xml version="1.0" encoding="UTF-8"?>
<ns2:CU_DE_Fitnesfirst_INVOIC_CSV xmlns:ns2="http://test.com">
  <Rechnungen>
    <Kopf>
      <K_Belegdatum>Belegdatum</K_Belegdatum>
      <K_Leistungsdatum>Leistungsdatum</K_Leistungsdatum>
      <K_VBelN>Faktura</K_VBelN>
    </Kopf>
    <Positionen>
      <P_Belegdatum>12092018</P_Belegdatum>
      <P_Leistungsdatum>22072018</P_Leistungsdatum>
      <P_VBelN>12345</P_VBelN>
    </Positionen>
  </Rechnungen>
  <Rechnungen>
    <Kopf>
      <K_Belegdatum>Belegdatum</K_Belegdatum>
      <K_Leistungsdatum>Leistungsdatum</K_Leistungsdatum>
      <K_VBelN>Faktura</K_VBelN>
    </Kopf>
    <Positionen>
      <P_Belegdatum>12092018</P_Belegdatum>
      <P_Leistungsdatum>29072018</P_Leistungsdatum>
      <P_VBelN>67890</P_VBelN>
    </Positionen>
  </Rechnungen>
</ns2:CU_DE_Fitnesfirst_INVOIC_CSV>

所需的输出:

 <?xml version="1.0" encoding="UTF-8"?>
<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
  <ns0:Message1>
    <ns2:CU_DE_Fitnesfirst_INVOIC_CSV xmlns:ns2="http://test.com">
      <Kopf>
        <K_Belegdatum>Belegdatum</K_Belegdatum>
        <K_Leistungsdatum>Leistungsdatum</K_Leistungsdatum>
        <K_VBelN>Faktura</K_VBelN>
      </Kopf>
      <Positionen>
        <P_Belegdatum>12092018</P_Belegdatum>
        <P_Leistungsdatum>22072018</P_Leistungsdatum>
        <P_VBelN>12345</P_VBelN>
      </Positionen>
    </ns2:CU_DE_Fitnesfirst_INVOIC_CSV>
    <ns2:CU_DE_Fitnesfirst_INVOIC_CSV xmlns:ns2="http://test.com">
      <Kopf>
        <K_Belegdatum>Belegdatum</K_Belegdatum>
        <K_Leistungsdatum>Leistungsdatum</K_Leistungsdatum>
        <K_VBelN>Faktura</K_VBelN>
      </Kopf>
      <Positionen>
        <P_Belegdatum>12092018</P_Belegdatum>
        <P_Leistungsdatum>29072018</P_Leistungsdatum>
        <P_VBelN>67890</P_VBelN>
      </Positionen>
    </ns2:CU_DE_Fitnesfirst_INVOIC_CSV>
  </ns0:Message1>
</ns0:Messages>

1 个答案:

答案 0 :(得分:0)

从身份模板开始,因为它将处理所有不变的现有节点的复制。

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

然后,您希望模板跳过ns2:CU_DE_Fitnesfirst_INVOIC_CSV,以便不将其复制到其原始位置

<xsl:template match="ns2:CU_DE_Fitnesfirst_INVOIC_CSV">
  <xsl:apply-templates />
</xsl:template>

相反,您需要一个匹配Rechnungen的模板,您可以在其中用其父元素的副本替换它

<xsl:template match="Rechnungen">
  <xsl:element name="{../name()}" namespace="{../namespace-uri()}">
    <xsl:apply-templates />
  </xsl:element>
</xsl:template>

尝试使用此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns2="http://test.com"
    version="2.0">

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

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

  <xsl:template match="ns2:CU_DE_Fitnesfirst_INVOIC_CSV">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="Rechnungen">
    <xsl:element name="{../name()}" namespace="{../namespace-uri()}">
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

注意,如果您使用的是XSLT 3.0,则可以稍微整理一下代码,然后执行此操作。...

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns2="http://test.com"
    version="3.0">

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

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="ns2:CU_DE_Fitnesfirst_INVOIC_CSV">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="Rechnungen">
    <xsl:variable name="currentChildren" select="node()" />
    <xsl:copy select="..">
      <xsl:apply-templates select="$currentChildren" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

还请注意,我不确定ns0:Messages是否在您的输入XML中,或者您是否要添加它。如果确实需要添加,只需将此模板添加到上述XSLT之一即可:

<xsl:template match="/">
  <ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
    <ns0:Message1>
      <xsl:apply-templates />
    </ns0:Message1>
  </ns0:Messages>
</xsl:template>