【问题标题】:xslt: traverse chain of ancestors in reverse orderxslt:以相反的顺序遍历祖先链
【发布时间】:2014-11-11 12:24:07
【问题描述】:

假设我有以下 xml 文档:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="FirstLevel">
    <xs:unique name="uniqueL2inL1">
      <xs:selector xpath="SecondLevel" />
      <xs:field xpath="@Name" />
    </xs:unique>
  </xs:element>
  <xs:element name="SecondLevel">
    <xs:unique name="uniqueL3inL2">
      <xs:selector xpath="ThirdLevel" />
      <xs:field xpath="@Name" />
    </xs:unique>
  </xs:element>
  <xs:element name="ThirdLevel">
    <xs:unique name="uniqueL4inL3">
      <xs:selector xpath="FourthLevel" />
      <xs:field xpath="@Name" />
    </xs:unique>
  </xs:element>
  <xs:element name="FourthLevel"/>
</xs:schema>

有哪些可能以正确的顺序获得从ThirdLevel元素到文档根的唯一定义“链”?

我想要为ThirdLevel 生成的输出例如:

FirstLevel
SecondLevel

要获得FirstLevel 的节点(例如root-element),我需要查询一个xs:element,它有一个xs:unique,但它的名字本身在xs:unique/xs:selector/@xpath 中没有其他地方使用。这个具体的查询是:

<xsl:variable name="root-element" select="//xs:element[xs:unique and not(//xs:element/xs:unique/xs:selector/@xpath = @name)]/@name"/>

现在我需要获取ThirdLevel 和$root-element 之间的所有节点。

我有一个递归调用的template,它带有两个参数(可以附加,但为了清楚起见将其放在一边)输出所有节点。

是否可以使用一个 xpath 进行查询?

问候

【问题讨论】:

    标签: xml xslt xsd ancestor


    【解决方案1】:

    我不确定整个方法对于复杂模式和任意 XPath 选择器是否有意义,但如果当前方法为您提供了您想要的输出,只是顺序错误,那么您可以简单地将输出存储在一个变量中并反转该变量输出值时的内容:

    <xsl:stylesheet version="2.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xs="http://www.w3.org/2001/XMLSchema" >
      <xsl:output method="text" />
      <xsl:template match="xs:element">
        <xsl:result-document href="chain_{@name}">
          <xsl:variable name="element-name" select="@name"/>
          <xsl:variable name="parent-name" select="//xs:unique/xs:selector[@xpath=$element-name]/@xpath"/>
          <xsl:if test="$parent-name != ''">
            <xsl:variable name="list" as="xs:string*">
              <xsl:call-template name="mytemplate">
                <xsl:with-param name="unique-block" select="//xs:unique/xs:selector[@xpath=$element-name]/.."/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:value-of select="reverse($list)" separator="&#10;"/>
          </xsl:if>
        </xsl:result-document>
      </xsl:template>
      <xsl:template name="mytemplate">
        <xsl:param name="unique-block"/>
        <xsl:variable name="parent-name" select="$unique-block/../@name"/>
        <xsl:sequence select="$parent-name"/>
        <xsl:variable name="unique-selector" select="//xs:unique/xs:selector[@xpath=$parent-name]/@xpath"/>
        <!-- evaluate and recurse, if needed: -->
        <xsl:if test="$unique-selector != ''">
          <xsl:call-template name="mytemplate">
            <xsl:with-param name="unique-block" select="//xs:unique/xs:selector[@xpath=$parent-name]/.." />
          </xsl:call-template>
        </xsl:if>
      </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-06
      • 2021-08-17
      • 2018-03-08
      • 2011-01-07
      相关资源
      最近更新 更多