如果满足条件,则形成多个父元素 - 使用 xslt 1

Form multiple parent elements if condition is met- using xslt 1

我有两种情况:

如果在 <SL id="L1S1"><pit ref="L1S1"> 等其他节点上找到文本“L1”(<L Id="L1">),我需要形成多个 L 节点。 SL 节点(即 <SL id="L1S1">)的 id 属性是使用 <L Id="L1"> 中的“L1”形成的。坑节点(即<pit ref="L1S1">)的ref属性也是使用<L Id="L1">中的“L1”形成的, 我需要检查“L1”是否存在于 SL 的 id 属性或 pit 的 ref 属性中,并形成所需的输出。

输入xml如下

<root>
  <L Id="L1">
    <test>ed</test>
    <SL id="L1S1">
      <check>
        <AId>1</AId>
      </check>
      <MD>
        <UnitNumber>1</UnitNumber>
      </MD>
    </SL>
<SL id="L1S2">
      <check>
        <AId>2</AId>
      </check>
      <MD>
        <UnitNumber>2</UnitNumber>
      </MD>
    </SL>
  </L>
  <cp>
    <current>
      <Amt>20154.00</Amt>
    </current>
    <pi>
      <pit ref="L1S1">
        <value>123</value>
      </pit>
<pit ref="L1S2">
        <value>1232</value>
      </pit>
    </pi>
  </cp>
</root>

预期输出应为:

<root>
  <L Id="L1">
    <SL id="L1S1">
      <check>
        <AId>1</AId>
      </check>
      <MD>
        <UnitNumber>1</UnitNumber>
      </MD>
    </SL>
    <pit ref="L1S1">
      <value>123</value>
    </pit>
  </L>
  <L Id="L1">
    <SL id="L1S2">
      <check>
        <AId>2</AId>
      </check>
      <MD>
        <UnitNumber>2</UnitNumber>
      </MD>
    </SL>
    <pit ref="L1S2">
      <value>1232</value>
    </pit>
  </L>
</root>
<root>
  <L Id="L1">
    <test>ed</test>    
  </L>
  <cp>
    <current>
      <Amt>20154.00</Amt>
    </current>
    <pi>
      <pit ref="L1S1">
        <value>123</value>
      </pit>
 <pit ref="L1S2">
        <value>1232</value>
      </pit>
    </pi>
  </cp>
</root>

预期输出应为:

<root>
  <L Id="L1">
    <pit ref="L1S1">
      <value>123</value>
    </pit>
  </L>
  <L Id="L1">
    <pit ref="L1S2">
      <value>1232</value>
    </pit>
  </L>
</root>

任何人都可以帮助我提供适用于这两种情况的解决方案吗?

上面的 xslt 适用于第一种情况,但无法用于第二种输入 xml,可能是我需要使用 contains() 或类似的东西,我不确定。

我正在使用 xslt1.0,但在为第二种情况形成每个 L1 节点时遇到问题。

<xsl:key name="pit" match="pit" use="@ref" />
<xsl:copy>
  <xsl:for-each select="L/SL">
    <xsl:element name="{../@Id}">
      <xsl:copy-of select="."/>
      <xsl:copy-of select="key('pit', @Id)"/>
    </xsl:element>
  </xsl:for-each>
</xsl:copy>

我想在第二种情况下 L/@Idpit/@ref 之间存在关系。现在我假设 pit/@ref 的前两个字符应该匹配 L/@Id.

如果这是正确的,你可以尝试这样的事情:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0"
 >
  
  <xsl:output method="xml" indent="yes"/>
  
  <xsl:key name="pit-SL" match="pit" use="@ref" />
  <xsl:key name="pit-L"  match="pit" use="substring(@ref,1,2)" />
  
  <xsl:strip-space elements="*"/>
  
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="L[SL]">
    <xsl:apply-templates select="SL"/>
  </xsl:template>
  
  <xsl:template match="SL">
    <L>
      <xsl:copy-of select="parent::L/@Id"/>
      <xsl:copy>
        <xsl:copy-of  select="@id"/>
        <xsl:apply-templates select="node()"/>
        <xsl:copy-of select="key('pit-SL',@id)"/>
      </xsl:copy>
    </L>
  </xsl:template>
  
  <xsl:template match="L[not(SL)]">
    <xsl:apply-templates select="key('pit-L',@Id)">
      <xsl:with-param name="L" select="."/>
    </xsl:apply-templates>
  </xsl:template>
  
  <xsl:template match="pit">
    <xsl:param name="L"/>
    <L>
      <xsl:copy-of select="$L/@Id"/>
      <xsl:copy-of select="."/>
    </L>
  </xsl:template>

  <xsl:template match="cp"/>
    
</xsl:stylesheet>