在xslt 1.0上为动态xpath使用值

时间:2018-08-23 12:56:05

标签: xml xslt xslt-1.0

我的问题/目标是:如何在firstPart中生成内容?

(我的编译器不能动态运行Evaluate()函数,它基于XSLT 1.0(VB.NET)。我只想使用开发板工具。)

输出应包含2个主要部分。在第一部分中,我想遍历该人并选择/ root / choosePerson中描述的那个人。第二部分由/ root / person中的所有人员组成。

现在变得越来越困难:在输出中,我应该获得一个ID属性,引用firstPart中的Person。第二部分还有一些其他算法,没有显示生日。

input.xml:

<root>
<person> <name>bart</name> <gender>m</gender> <birth>01.01.2016</birth> </person>
<person> <name>lisa</name> <gender>w</gender> <birth>01.01.2015</birth> </person>
<person> <name>homer</name> <gender>m</gender> <birth>01.01.2014</birth> </person>
<choosePerson>choose person: 1</choosePerson><!-- it really consist of string and a number -->
<root>

output.xml:

<MyNewRoot>
<firstPart>
<person id="1" gender="m"><name>bart</name> <birth>01.01.2016</birth> </person>
<firstPart>
<secondPart>
<person id="1" gender="m"> <name>bart</name>  </person>
<person id="2" gender="w"> <name>lisa</name>  </person>
<person id="3" gender="m"> <name>homer</name>  </person>
</secondPart>
<MyNewRoot>

我该怎么办?我可以先从第二部分开始:

<xsl:template match="/">
<firstPart>

<firstPart>
<secondPart>
<xsl:apply-templates select="//root/person"/>
</secondPart>
</xsl:template>

<xsl:template match="//root/person"">
<!-- incomplete code (for the sake of clarity), but here I copy the values and create an id through the position() method -->
</xsl:template>

我知道动态XPath是不可能的,并且还存在混合变体。但是因为“ choosePerson”而需要动态Xpath吗?

1 个答案:

答案 0 :(得分:0)

这里不需要任何动态xpath。...

您可以将位置作为参数传递给与person匹配的模板,以及要排除的子节点的名称

<xsl:template match="//root/person">
  <xsl:param name="position" select="position()" />
  <xsl:param name="excludeChild" />

因此,在第一部分中,您将定义一个要选择的人的位置的变量,然后将模板应用于该人,并将变量作为参数传递给

<xsl:variable name="choose" select="substring-after(root/choosePerson, ': ')" />
<xsl:apply-templates select="root/person[position()=$choose]">
  <xsl:with-param name="position" select="$choose" />
</xsl:apply-templates>

对于第二部分,您可以使用默认位置,但是传入参数以排除“出生”元素

<xsl:apply-templates select="root/person">
  <xsl:with-param name="excludeChild" select="'birth'" />
</xsl:apply-templates>

尝试此XSLT。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output indent="yes" />

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

  <xsl:template match="/">
    <firstPart>
      <xsl:variable name="choose" select="substring-after(root/choosePerson, ': ')" />
      <xsl:apply-templates select="root/person[position()=$choose]">
        <xsl:with-param name="position" select="$choose" />
      </xsl:apply-templates>
    </firstPart>
    <secondPart>
      <xsl:apply-templates select="root/person">
        <xsl:with-param name="excludeChild" select="'birth'" />
      </xsl:apply-templates>
    </secondPart>
  </xsl:template>

  <xsl:template match="//root/person">
    <xsl:param name="position" select="position()" />
    <xsl:param name="excludeChild" />
    <person id="{$position}" gender="{gender}">
      <xsl:apply-templates select="*[local-name() != $excludeChild]" />
    </person>
  </xsl:template>

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