Xml XPath访问外部循环
我有一个包含记录的XML文档。每个记录都有一个UI元素和一个TreeNum元素。我试图编写一个XSLT,从记录中每个树编号的父树编号生成父记录。父编号是树编号减去1位,树编号仅为2个字符的记录没有父树编号。例如,UI为“pear”的第二条记录的树编号为“A11”,因此其父树编号应为“A1”。我想找到保存父树编号的记录的UI。因此,对于“pear”记录,父记录UI将是“apple” XMLXml XPath访问外部循环,xml,xslt,xpath,Xml,Xslt,Xpath,我有一个包含记录的XML文档。每个记录都有一个UI元素和一个TreeNum元素。我试图编写一个XSLT,从记录中每个树编号的父树编号生成父记录。父编号是树编号减去1位,树编号仅为2个字符的记录没有父树编号。例如,UI为“pear”的第二条记录的树编号为“A11”,因此其父树编号应为“A1”。我想找到保存父树编号的记录的UI。因此,对于“pear”记录,父记录UI将是“apple” XML 苹果 A1 A5 梨 A11 巧克力 A13 A51 XSL 预期产量 苹果 A1 A5 梨 A1
苹果
A1
A5
梨
A11
巧克力
A13
A51
XSL
预期产量
苹果
A1
A5
梨
A11
苹果
巧克力
A13
苹果
A51
苹果
我曾尝试在网上寻找解决方案,但我发现这个问题很难描述,因此很难找到解决方案。我感谢任何帮助,如果需要,我会尽力澄清更多
我用于选择父UI的XPath不起作用,返回一个空的ParentUI元素,因此XPath表达式不正确,我尝试使用变量选择外部循环中的记录元素和“./”运算符,但没有幸运地选择我需要的内容。请尝试:
<ParentUI><xsl:value-of select = "./preceding::UI[following-sibling::TreeNum[.=substring(.,1,2)]]"/></ParentUI>
输出:
<?xml version="1.0" encoding="UTF-8"?>
<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</ParentUI>
</Record>
苹果
A1
A5
梨
A11
苹果
巧克力
A13
苹果
A51
苹果
我建议您这样做:
XSLT1.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>
请注意,显示的结果是一个XML片段。格式良好的XML文档必须具有单个根元素。在更改树编号值时未生成正确的输出。在我看来,输出似乎是正确的:
<ParentUI><xsl:value-of select = "./preceding::UI[following-sibling::TreeNum[.=substring(.,1,2)]]"/></ParentUI>
<?xml version="1.0" encoding="UTF-8"?>
<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</ParentUI>
</Record>
<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>