我有一些XML数据(客户数据,所以任意的例子:)
<attributes>
<attribute>
<attribute_type xsi:type="xsd:string">
parent
</attribute_type>
<attribute_id xsi:type="xsd:string">
ABC123
</attribute_id>
<someValue xsi:type="xsd:string">
123456
</someValue>
</attribute>
<attribute>
<attribute_type xsi:type="xsd:string">
child
</attribute_type>
<attribute_id xsi:type="xsd:string">
ABC123
</attribute_id>
<someValue xsi:type="xsd:string">
null
</someValue>
</attribute>
</attributes>
每个attribute
都有一个“父”和“子”,它们不是嵌套的,而是包含一个标识符,用于提供两者之间的通用性。每个父母都应该跟着孩子,所以这些应该总是按顺序。
导入数据时,我只想导入'child',但父项包含我要与子项导入的信息(在本例中为someValue
)。
我尝试在迭代时设置一个变量,以便它可以向前传递一个值,即:
<xsl:for-each select="attributes/attribute">
<xsl:if test="attribute_type = 'parent' ">
<xsl:variable name="testId" select="normalize-space(attribute_id)"/>
<xsl:variable name="testValue" select="normalize-space(someValue)"/>
</xsl:if>
<xsl:if test="attribute_type != 'parent' ">
attribute.<xsl:value-of select="position()"/>.id=<xsl:value-of select="normalize-space(attribute_id)"/>
<xsl:if test="attribute_id = $testId">
attribute.<xsl:value-of select="position()"/>.Value=<xsl:value-of select="$testValue"/>
</xsl:if>
</xsl:for-each>
显然有很多数据和这里缺少值,但我已经减少了这一点,以保持其可读性。本质上,我只想输出'子'值,但我想通过变量将父值传递给子的输出。
预期输出为:
attribute.2.id = ABC123
attribute.2.Value = 123456
(由于迭代,我预计第一个position()
为'2'但第一个parent
未输出为position() = 1
)
以上不起作用,我认为可能与变量范围有关。
position()
使得简单地“输出”数据变得困难,除非我用<xsl:value-of select="position()+1"/>
类型的东西试图将其推向前方,但我不是确定它会变得强大或可靠。
这是否可行(因为我无法修改原始XML数据)?
答案 0 :(得分:1)
如果您有交叉引用,请使用key来关注并访问该值:
<xsl:key name="parent" match="attribute[normalize-space(attribute_type) = 'parent']" use="normalize-space(attribute_id)"/>
<xsl:template match="/">
<xsl:for-each select="attributes/attribute[normalize-space(attribute_type) != 'parent']">
attribute.<xsl:number/>.id=<xsl:value-of select="normalize-space(attribute_id)"/>
<xsl:if test="key('parent', normalize-space(attribute_id))">
attribute.<xsl:number/>.Value=<xsl:value-of select="normalize-space(key('parent', normalize-space(attribute_id))/someValue)"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
另一种方法是从preceding-sibling::attribute[1][normalize-space(attribute_id) = normalize-space(current()/attribute_id)]
内导航到for-each
。
如果你真的想要一个构造来&#34;迭代&#34;按顺序存储每个步骤的变量,然后移到XSLT 3和xsl:iterate
(https://www.w3.org/TR/xslt/#iterate)。