首页 > 解决方案 > 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 表达式不正确,我尝试使用变量来选择外循环中的记录元素和“../ " 运算符,但没有运气选择我需要的东西。

标签: xmlxsltxpath

解决方案


我建议你这样尝试:

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>

推荐阅读