【问题标题】:xslt get the immediate following siblingxslt 获取紧随其后的同级
【发布时间】:2017-08-30 18:35:40
【问题描述】:

我有以下几点:

 <root>
  <html>
   <table
    <tr> 
     <td width="1%" height="20"></td>
     <td width="18%">Book Location </td>
     <td width="81%">Technology (Applied sciences) Circulation</td>
    </tr>

我正在 xslt 下面尝试获取 td 的节点内容为“Book Location”的直接节点内容:

<?xml version="1.0" encoding="utf-8"?>
 <xsl:stylesheet version="1.0"
 xmlns:marc="http://www.loc.gov/MARC21/slim"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text" indent="yes" />

 <xsl:template match="root">
  <xsl:for-each select="html">
  <xsl:text>START HERE</xsl:text>
  <xsl:text>&#13;&#10;</xsl:text>
  <xsl:text>=LDR  00000nam  2200000Ia 4500</xsl:text>
  <xsl:text>&#13;&#10;</xsl:text>

  <xsl:if test="//*[text()='Book Location ']">
   <xsl:text>=952  \\$cLocation: </xsl:text>
   <xsl:value-of select="following-sibling" />
  </xsl:if> 

  </xsl:for-each>

  </xsl:template>
 </xsl:stylesheet>

我不知道在这部分放什么: 或者如果有更好的方法来做到这一点? 提前致谢,祝您有美好的一天!

【问题讨论】:

  • 所以你想发出文本“技术(应用科学)循环”?
  • 是的,我想从这个数据集中获取“技术(应用科学)流通”。

标签: html xslt xslt-1.0 xslt-2.0 marc


【解决方案1】:

您的模板表明您正在像程序语言程序员一样思考。 XSLT 可以或多或少地用那个习语来写,但它不是 XSLT 的自然习语。以这种方式编写的代码往往比更自然的代码更长、更混乱。特别是,虽然for-each 元素有很好的用途,但它们通常带有一点代码味道。

这对我来说似乎更自然,而且似乎有效(但我必须对您输入的修改版本进行测试,因为您提供的不是有效的 XML):

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes" />

  <xsl:template match="/root/html">
    <xsl:text>START HERE</xsl:text>
    <xsl:text>&#13;&#10;</xsl:text>
    <xsl:text>=LDR  00000nam  2200000Ia 4500</xsl:text>
    <xsl:text>&#13;&#10;</xsl:text>
    <xsl:apply-templates select="descendant::td[text() = 'Book Location ']" />
  </xsl:template>

  <xsl:template match="td">
   <xsl:text>=952  \\$cLocation: </xsl:text>
   <xsl:value-of select="following-sibling::*[1]" />
  </xsl:template> 

</xsl:stylesheet>

注意:

  • 更具体的匹配表达式消除了对原始文件中 for-each 的需要
  • 不是试图将整个转换放入一个模板,而是使用单独的模板来转换单独的元素。这不仅更简洁,而且有助于简化表达式,因为每个模板都与它自己的上下文相关联,关于哪些表达式被评估
  • 要使用“following-sibling”作为轴名称,而不是元素名称,您必须附加一个双冒号并至少附加某种节点测试
  • “following-sibling”轴可以包含多个节点,因此如果您只想要紧随其后的一个,则需要指定(如上)
  • 我可能选择直接转换包含该位置的td,而不是通过其标签td 的模板间接转换。这对我来说似乎更干净,但我没有这样做,因为它的语义略有不同。

【讨论】:

  • 同意您使用正确的 XSL 习语,如果可以,我会再添加一个以供您解释。
  • 我忘记在我的帖子中指出我正在将记录转换为文本而不是 xml。您的解决方案也有效,我将进一步研究。干杯!
【解决方案2】:

你可以用这个:

<xsl:value-of select="//*[text()='Book Location ']/following-sibling::*[1]" />

而不是

<xsl:value-of select="following-sibling" />

【讨论】:

  • 感谢鲁佩什!我试过了,但仍然是一个空白值。
  • 我已经更新了答案,现在这对你有用
  • 再次感谢鲁佩什!您的解决方案与 John Bollinger 的解决方案一样有效。我会赞成你们两个。干杯!
猜你喜欢
  • 1970-01-01
  • 2018-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 2012-04-30
  • 1970-01-01
  • 2015-05-13
相关资源
最近更新 更多