如何使用 xslt 选择节点的祖父母

发布于 2024-09-17 22:58:22 字数 1118 浏览 4 评论 0 原文

我所处的情况是,我只能测试子节点,但我必须将标签应用于该子节点的祖节点。

我尝试过使用:

<xsl:call-template name="grandparent" select="parent::parent::node()"/>

和:

<xsl:call-template name="grandparent" select="ancestor::node [@nameofgrandparentnode]"/>

但都不起作用。

祖父母节点的级别不固定,所以我想我也不能使用[@level=#]。任何有关如何选择它的想法将不胜感激。

编辑:--这部分已作为新问题发布:

xslt 根据其孙节点的属性值选择祖父节点

使用下面的建议选择节点是有效的。谢谢!但是我还需要通过祖父母或孙节点的属性进行测试。

我已经尝试过:

<xsl:template name"one" match="grandparentnode">
 <Tag1>
  <xsl:apply-templates select="parentNode" />
 </Tag1>
</xsl:template>

<xsl:template name="two" match="grandparentnode[*/*/@grandchildattr='attrValue']">
 <Tag2>
     <xsl:apply-templates select="parentNode" />
 </Tag2>
</xsl:template>

但是模板“two”总是被调用,并且“”总是被插入。即使对于属性值不等于“attrValue”的孙节点也是如此。

我在这里错过了什么吗?

I'm in a situation where I can only test for the child node, but I have to apply tags to the grandparent of this child node.

I've tried using:

<xsl:call-template name="grandparent" select="parent::parent::node()"/>

and:

<xsl:call-template name="grandparent" select="ancestor::node [@nameofgrandparentnode]"/>

But neither works.

The level of the grandparent node is not fixed, so I figure I can't use [@level=#] either. Any ideas on how to select it would be greatly appreciated.

EDIT: -- This part has been posted as a new question:

xslt select grandparent node depending on an attribute value of its grandchild node

Selecting the node using the suggestions from below worked. Thanks! However I also need to test by the attribute of the grandparent or grandchild node.

I've tried:

<xsl:template name"one" match="grandparentnode">
 <Tag1>
  <xsl:apply-templates select="parentNode" />
 </Tag1>
</xsl:template>

<xsl:template name="two" match="grandparentnode[*/*/@grandchildattr='attrValue']">
 <Tag2>
     <xsl:apply-templates select="parentNode" />
 </Tag2>
</xsl:template>

However template "two" always gets called, and "" is always inserted. Even for grandchild nodes whose attribute value is not equal to 'attrValue'.

Am I missing something here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

美男兮 2024-09-24 22:58:22

我尝试过使用:

; 

和:

>

但两者都不起作用。

当然它不会“工作”,因为 指令没有 select 属性!

您可以使用 指令的 子指令传递参数,如下所示:

<xsl:call-template name="compute">
  <xsl:param name="pAncestor" select="someExpression"/>
</xsl:call-template>

对于 的 >select 属性 用途

对于真正的祖父母:

../..

用于名为 someName 的最近祖先元素:

ancestor::someName[1]

对于名称包含在变量 $ancName 中的最接近的祖先元素:

ancestor::*[name()=$ancName][1]

I've tried using:

<xsl:call-template name="grandparent" select="parent::parent::node()"/> 

and:

<xsl:call-template name="grandparent" select="ancestor::node[@nameofgrandparentnode]"/>

But neither works.

Certainly it will not "work", because the <xsl:call-template> instruction doesn't have a select attribute!

You may pass parameters using <xsl:with-param> children of the <xsl:call-template> instruction, like this:

<xsl:call-template name="compute">
  <xsl:param name="pAncestor" select="someExpression"/>
</xsl:call-template>

For the select attribute of the <xsl:with-param> Use:

For a real grandparent:

../..

for the closest ancestor element with name someName:

ancestor::someName[1]

for the closest ancestor element with name contained in the variable $ancName:

ancestor::*[name()=$ancName][1]
剑心龙吟 2024-09-24 22:58:22

我所处的情况是,我只能测试子节点,但我必须将标签应用于该子节点的祖节点。

XSLT 不是过程式编程,因此您必须以不同的方式思考问题。

如果我理解正确的话,您想要将新标签(额外的子元素或属性?)注入到您的 XML 中,但是当您找到特定的后代时,您希望将其添加到祖先中。一旦您遇到孩子,您的示例代码似乎会尝试针对祖父母。不幸的是,这可能为时已晚。

当引擎遇到您想要修改的元素(在您的情况下是祖父母)时,您可能需要注入新元素/属性,而不是当它遇到与条件匹配的子元素时(否则您将最终向子级添加元素或属性)

考虑此输入(grandparent =“album”,grandchild =“label”):

<?xml version="1.0" encoding="UTF-8"?>

<album> 
  <title>Sgt. Pepper's Lonely Hearts Club Band</title>  
  <artist>The Beatles</artist>  
  <year>1967</year>  
  <labels> 
    <label>Parlophone</label>  
    <label>Capitol</label> 
  </labels> 
</album>

我想根据是否存在某个标签来修改album。请记住,目标节点的一般格式是:target-node[target-condition]。要修改任何具有 Capitol 标签孙元素的 album 元素,我将使用以下内容:

album[*/label='Capitol']

因此,考虑使用此样式表向 添加一个新属性和 2 个新子元素>专辑符合我的条件:

<?xml version="1.0" encoding="UTF-8"?>

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

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

  <xsl:template match="album[*/label='Capitol']"> 
    <xsl:copy> 
      <xsl:apply-templates select="@*"/>
      <xsl:attribute name="new-attribute">A Capitol Record</xsl:attribute>  
      <new-element1/> 
      <xsl:apply-templates select="node()"/>  
      <new-element2/> 
    </xsl:copy> 
  </xsl:template> 

</xsl:stylesheet>

输出(手动格式化):

<?xml version="1.0" encoding="UTF-8"?>
<album new-attribute="A Capitol Record"> 
  <new-element1/> 
  <title>Sgt. Pepper's Lonely Hearts Club Band</title>  
  <artist>The Beatles</artist>  
  <year>1967</year>  
  <labels> 
    <label>Parlophone</label>  
    <label>Capitol</label> 
  </labels> 
  <new-element2/>
</album>

一些沙箱测试资源:

I'm in a situation where I can only test for the child node, but I have to apply tags to the grandparent of this child node.

XSLT isn't procedural programming, so you have to think about things a little differently.

If I understand correctly, you want to inject new tags (additional child elements or attributes?) into your XML, but you want to add it to an ancestor when you find a specific descendant. Your example code appears to try to target the grandparent once you come across the child. Unfortunately, this may be too late.

You may need inject the new element/attribute when engine comes across the element you want to modify (the grandparent in your case), not when it comes across the child that matches the condition (or else you'll end up adding elements or attributes to the child)

Consider this input (grandparent="album", grandchild="label"):

<?xml version="1.0" encoding="UTF-8"?>

<album> 
  <title>Sgt. Pepper's Lonely Hearts Club Band</title>  
  <artist>The Beatles</artist>  
  <year>1967</year>  
  <labels> 
    <label>Parlophone</label>  
    <label>Capitol</label> 
  </labels> 
</album>

I want to modify the album based on whether a certain label is present. Remember the general format for targeting nodes is: target-node[target-condition]. To modify any album elements that have a Capitol label grandchild element, I'd use this:

album[*/label='Capitol']

So consider this stylesheet to add a new attribute and 2 new child elements to album's that match my condition:

<?xml version="1.0" encoding="UTF-8"?>

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

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

  <xsl:template match="album[*/label='Capitol']"> 
    <xsl:copy> 
      <xsl:apply-templates select="@*"/>
      <xsl:attribute name="new-attribute">A Capitol Record</xsl:attribute>  
      <new-element1/> 
      <xsl:apply-templates select="node()"/>  
      <new-element2/> 
    </xsl:copy> 
  </xsl:template> 

</xsl:stylesheet>

Output (manually formatted):

<?xml version="1.0" encoding="UTF-8"?>
<album new-attribute="A Capitol Record"> 
  <new-element1/> 
  <title>Sgt. Pepper's Lonely Hearts Club Band</title>  
  <artist>The Beatles</artist>  
  <year>1967</year>  
  <labels> 
    <label>Parlophone</label>  
    <label>Capitol</label> 
  </labels> 
  <new-element2/>
</album>

Some sandbox test resources:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文