如果 id 与给定的过滤器 XSLT 1 匹配,则将 parent id 属性移动到第一个 child

Move parent id attribute to it's first child if id matches the given filter XSLT 1

我需要将 ol/ul 标签的 id 属性移动到它的第一个 li 标签 child 只有当 id 的值具有正确的 objectId 模式如 [0-9a-fA-F ]{24} 这意味着 id 应仅包含 0123456789ABCDEFabcdef,长度应为 24。如果 id 无效,则从 ul/ol 标记中删除该 id 属性,如果 id 正确,则将其移至第一个 child 并将其名称更改为 OID。 提前致谢。 我的 xml:

<root>
   <ul id="623dcc9772fc494aa2252885">
      <li>Donate the shelters so animals can be homed easier.</li>
      <li>If you see a dog on the road, take it to a shelter</li>
   </ul>
      <ul id="623dcc9772fc494aa2252gghghghgg885">
      <li>Donate the shelters so animals can be homed easier.</li>
      <li>If you see a dog on the road, take it to a shelter</li>
   </ul>
</root>

期望的输出:

<root>
   <ul>
      <li OID="623dcc9772fc494aa2252885">Donate the shelters so animals can be homed easier. 
      </li>
      <li>If you see a dog on the road, take it to a shelter</li>
   </ul>
      <ul>
      <li>Donate the shelters so animals can be homed easier.</li>
      <li>If you see a dog on the road, take it to a shelter</li>
   </ul>
</root>

我尝试了什么:

<xsl:template match="li[not(@id)][1]">
        <li>
            <xsl:if test="ancestor::ul[1]/@id != '' or ancestor::ol[1]/@id != '' ">
                <xsl:attribute name="oid">
                    <xsl:choose>
                        <xsl:when test="ancestor::ol[1]/@id != ''">
                            <xsl:value-of select="ancestor::ol[1]/@id"/>
                        </xsl:when>
                        <xsl:when test="ancestor::ul[1]/@id != ''">
                            <xsl:value-of select="ancestor::ul[1]/@id"/>
                        </xsl:when>
                    </xsl:choose>
                </xsl:attribute>
            </xsl:if>
             <!--do not forget to copy possible other attributes -->
            <xsl:apply-templates select="@* | node()"/>
        </li>
    </xsl:template>

但这还会添加与我的过滤器不匹配的 ID。

这应该有所帮助。如果您有任何问题,请告诉我。

<xsl:template match="ul">
  <xsl:choose>
    <xsl:when test="translate(@id, '0123456789ABCDEFabcdef', '') = ''
                    and string-length(@id) = 24">
      <xsl:copy>
        <xsl:apply-templates select="li[1]" mode="move">
          <xsl:with-param name="id" select="@id"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="li[position() &gt; 1]"/>
      </xsl:copy>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy>
        <xsl:apply-templates select="node()"/>
      </xsl:copy>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>  

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

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

<xsl:template match="li" mode="move">
  <xsl:param name="id"/>
  <xsl:copy>
    <xsl:if test="not(boolean(@id))">
      <xsl:attribute name="id">
        <xsl:value-of select="$id"/>
      </xsl:attribute>
    </xsl:if>
    <xsl:apply-templates select="node()|@*" mode="move"/>
  </xsl:copy>
</xsl:template>

这也有效

<xsl:template match="li[not(@id)][1]">
    <li>
        <xsl:if test="ancestor::ul[1]/@id != '' or ancestor::ol[1]/@id != ''">
            <!--<xsl:attribute name="bulb-id">-->
                <xsl:choose>
                    <xsl:when test="ancestor::ol[1]/@id != '' and translate(ancestor::ol[1]/@id, '0123456789ABCDEFabcdef', '') = '' and string-length(ancestor::ol[1]/@id) = 24">
                        <xsl:attribute name="bulb-id">
                            <xsl:value-of select="ancestor::ol[1]/@id"/>
                        </xsl:attribute>
                    </xsl:when>
                    <xsl:when test="ancestor::ul[1]/@id != '' and translate(ancestor::ul[1]/@id, '0123456789ABCDEFabcdef', '') = '' and string-length(ancestor::ul[1]/@id) = 24">
                        <xsl:attribute name="bulb-id">
                            <xsl:value-of select="ancestor::ul[1]/@id"/>
                        </xsl:attribute>
                    </xsl:when>
                </xsl:choose>
            <!--</xsl:attribute>-->
        </xsl:if>
        <!-- do not forget to copy possible other attributes -->
        <xsl:apply-templates select="@* | node()"/>
    </li>
</xsl:template>

<!-- remove @id from ol, ul (but only when it contains li in it's child) -->
<xsl:template match="ol[li]/@id | ul[li]/@id"/>