如何使用 XSLT 保留具有相同元素名称的 xml 的特定部分

How to retain specific part of an xml with same element names using XSLT

我有一个输入 xml 文件和一个 XSLT 脚本。 我的输入 xml :

<?xml version="1.0" ?>
<Lib>
  <book>---</book>            <!-- from here -->
  <regn settr="---" value="---" />
  <regn settr="---" value="---" />
  ...
  <regn settr="---" value="---" />
  <regn settr="---">
    <pointall>
      <author settr="---">
        <point>
          <entry settr="---" value="---" />
        </point>
      </author> 
      <author settr="---">
        <point>
          <entry settr="---" value="---" />
        </point>
      </author>
       ...
       ...
    </pointall>    
  </regn>              <!-- to here -->
  <regn settr="register">
    <card>
      <author settr="register">
        <note>
          <book>---</book>
          <regn settr="---" value="---" />
          <regn settr="---">
            <pointall>
              <author settr="---">
                <point>
                  <some settr="---" value="" />
                </point>
              </author>
            </pointall>
          </regn>
        </note>
      </author>
    </card>
  </regn>
  <regn settr="write">
    <card>
      <author settr="write">
        <note>
          <book>---</book>
          <regn settr="---" value="---" />
            <pointall />
        </note>
      </author>
    </card>
  </regn>
  ...
  ...
  <regn settr="...">
    <card>
      <author settr="...">
        ...
      </author>
    </card>
  </regn>
  <regn settr="---" value="---" />
</Lib>

我正在对从 <regn settr="register"> 开始然后向下的 regn 元素应用 XSLT 模板转换。我的 XSLT 看起来像这样:

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

<xsl:template match="/Lib">
    <xsl:copy>
     <regn settr="Librarian">
      <xsl:copy-of select="regn/card"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

应用并将我的输入 xml 转换为以下输出 xml :

<Lib>
  <regn settr="Librarian">
    <card>
      <author settr="register">
        <note>
          <book>---</book>
          <regn settr="---" value="---" />
          <regn settr="---">
            <pointall>
              <author settr="---">
                <point>
                  <some settr="---" value="" />
                </point>
              </author>
            </pointall>
          </regn>
        </note>
      </author>
    </card>
    <card>
      <author settr="write">
        <note>
          <book>---</book>
          <regn settr="---" value="---" />
            <pointall />
        </note>
      </author>
    </card>
  ...
  ...
    <card>
      <author settr="...">
        ...
      </author>
    </card>
  </regn>
  <regn settr="---" value="---" />
</Lib>

即它将 <regn settr="register"><regn settr="write"> 和随后的 <regn settr="..."> 元素全部转换为一个元素,即 <regn settr="Librarian">.

但是我没有得到<Lib>之后和<regn settr="register">之前的内容,即我在评论行中提到的从“从这里”到“到这里”的内容。我也需要保留这些内容。此外,registerwrite 以及未来在 regn settr 元素中可能出现的任何其他值都是虚拟值,可能无法固定每个输入文件。

预期输出:

<?xml version="1.0" ?>
<Lib>
<book>---</book>            <!-- from here -->
  <regn settr="---" value="---" />
  <regn settr="---" value="---" />
  ...
  <regn settr="---" value="---" />
  <regn settr="---">
    <pointall>
      <author settr="---">
        <point>
          <entry settr="---" value="---" />
        </point>
      </author> 
      <author settr="---">
        <point>
          <entry settr="---" value="---" />
        </point>
      </author>
       ...
       ...
    </pointall>    
  </regn>              <!-- to here -->
  <regn settr="Librarian">
    <card>
      <author settr="register">
        <note>
          <book>---</book>
          <regn settr="---" value="---" />
          <regn settr="---">
            <pointall>
              <author settr="---">
                <point>
                  <some settr="---" value="" />
                </point>
              </author>
            </pointall>
          </regn>
        </note>
      </author>
    </card>
    <card>
      <author settr="write">
        <note>
          <book>---</book>
          <regn settr="---" value="---" />
            <pointall />
        </note>
      </author>
    </card>
  ...
  ...
    <card>
      <author settr="...">
        ...
      </author>
    </card>
  </regn>
  <regn settr="---" value="---" />
</Lib>

我尝试了类似的方法,但我没有得到想要的输出:

  <xsl:template match="/Lib">
  <xsl:copy-of select="."/>
    <xsl:copy>
        <regn settr="Librarian">
            <xsl:apply-templates select="regn/card"/>
        </regn>
    </xsl:copy>
</xsl:template>

如果有人能帮助我,我将不胜感激?谢谢!

我认为您可能只需要身份转换加上属性的一项更改,例如

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

<xsl:template match="regn/@settr[. = 'register']">
    <xsl:attribute name="{name()}">Librarian</xsl:attribute>
</xsl:template>