xml - XPath 访问外循环
问题描述
我有一个带有记录的 XML 文档。每条记录都有一个 UI 元素和一个 TreeNum 元素。我正在尝试编写一个 XSLT 来从记录中每个树号的父树号生成父记录。父编号是树编号减去 1 位,树编号只有 2 个字符的记录没有父树编号。例如,UI 为“pear”的第二条记录的树编号为“A11”,因此它的父树编号应为“A1”。我想找到包含父树编号的记录的 UI。因此对于“pear”记录,父记录 UI 将是“apple”。
XML
<RecordSet>
<Record>
<UI>apple</UI>
<TreeNum>A1</TreeNum>
<TreeNum>A5</TreeNum>
</Record>
<Record>
<UI>pear</UI>
<TreeNum>A11</TreeNum>
</Record>
<Record>
<UI>chocolate</UI>
<TreeNum>A13</TreeNum>
<TreeNum>A51</TreeNum>
</Record>
</RecordSet>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd ="http://www.w3.org/2001/XMLSchema#">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select = "RecordSet/Record">
<Record>
<UI><xsl:value-of select = "UI/text()"/></UI>
<xsl:for-each select = "TreeNum">
<TreeNumber><xsl:value-of select = "text()"/></TreeNumber>
<xsl:if test = "string-length(text()) > 2">
<ParentUI><xsl:value-of select = "../Record[UI/text() = substring(TreeNum/text(), 0, string-length(text())-1)]/UI[text()]"/></ParentUI>
</xsl:if>
</xsl:for-each>
</Record>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
预期产出
<Record xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
<UI>apple</UI>
<TreeNumber>A1</TreeNumber>
<TreeNumber>A5</TreeNumber>
</Record>
<Record xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
<UI>pear</UI>
<TreeNumber>A11</TreeNumber>
<ParentUI>apple</ParentUI>
</Record>
<Record xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
<UI>chocolate</UI>
<TreeNumber>A13</TreeNumber>
<ParentUI>apple</ParentUI>
<TreeNumber>A51</TreeNumber>
<ParentUI>apple</TreeNumber>
</Record>
我试图在网上寻找解决方案,但是我发现这个问题很难描述,因此很难找到解决方案。我感谢任何帮助,并会在需要时尝试澄清更多。
我用来选择父 UI 的 XPath 不起作用并返回一个空的 ParentUI 元素,所以是 XPath 表达式不正确,我尝试使用变量来选择外循环中的记录元素和“../ " 运算符,但没有运气选择我需要的东西。
解决方案
我建议你这样尝试:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd ="http://www.w3.org/2001/XMLSchema#">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="rec" match="Record" use="TreeNum" />
<xsl:template match="/RecordSet">
<xsl:for-each select="Record">
<Record>
<xsl:copy-of select="UI"/>
<xsl:for-each select="TreeNum">
<xsl:copy-of select="."/>
<xsl:variable name="parent" select="key('rec', substring(., 1, string-length(.) - 1))" />
<xsl:if test="$parent">
<ParentUI>
<xsl:value-of select="$parent/UI"/>
</ParentUI>
</xsl:if>
</xsl:for-each>
</Record>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
推荐阅读
- java - Spring Boot JPA:@Modifying @Query 没有效果
- php - PHP array_search通过变量在多维数组中
- mysql - SpringBoot 使用 Hibernate 与 Mysql 集成
- android - Smack 中的聊天标记 (XEP-0333)
- django - Django:如何测试无效的对象创建
- javascript - 检查嵌套括号是否平衡的 JavaScript 正则表达式
- javascript - D3 基于名称而不是索引链接节点
- hibernate - 使用 Java Spring MVC 上传 FOLDER 函数
- html - 在 jinja 框架中存储表单信息
- asp.net - 在.Net中从服务器传输压缩文件