繁体   English   中英

xslt节点集在关键功能中的使用-按父级属性查找子级

[英]xslt node-set use in key function - find children by parent attribute

我有一个XML文件。

<?xml version="1.0" encoding="UTF-8"?>
<XML>   
    <Items>
        <ItemRef ID='answer'></ItemRef>
        <ItemRef ID='number'></ItemRef>
        <ItemRef ID='delete'></ItemRef>
        <ItemRef ID='remove'></ItemRef>
    </Items>
    <ItemDef ID='anwser'></ItemDef>
    <ItemDef ID='number'>
        <EnumItemRef EID = '1'></EnumItemRef>
    </ItemDef>
    <ItemDef ID='delete'>
        <EnumItemRef EID = '2'></EnumItemRef>
    </ItemDef>        
    <ItemDef ID='remove'></ItemDef>
    <EnumItem EID="1">
        <EnumItem Value = '1'></EnumItem>
        <EnumItem Value = '2'></EnumItem>
        <EnumItem Value = '3'></EnumItem>
    </EnumItem>
    <EnumItem EID="2">
        <EnumItem Value = 'yes'></EnumItem>
        <EnumItem Value = 'no'></EnumItem>
    </EnumItem>
</XML>

我需要转换成这样的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<XML>   
    <Items>
        <ItemRef ID='newid_answer'></ItemRef>
        <ItemRef ID='newid_number'></ItemRef>
    </Items>
    <ItemDef ID='newid_answer'></ItemDef>
    <ItemDef ID='newid_number'>
        <EnumItemRef EID = '1'></EnumItemRef>
    </ItemDef>        
    <EnumItem EID="1">
        <EnumItem Value = '1'></EnumItem>
        <EnumItem Value = '2'></EnumItem>
        <EnumItem Value = '3'></EnumItem>
    </EnumItem>
</XML>

我有以下XSLT 1.0文件。 这样,我就可以创建所需的Items和ItemDef。 我只是想念一个如何找到对应的EnumItemRef和EnumItem的想法。 我要么必须检查当前的ItemDef是否有一个名为EnumItemRef的子项,要么可以用一个键函数来解决它(可能是更好的解决方案)。 我都尝试了两次,但无法正常工作。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:variable name="Items">
    <Item ID="answer">newid_answer</Item>
    <Item ID="number">newid_number</Item>
</xsl:variable>

<xsl:key name="get_Enum_by_ID" match="/XML/ItemDef/EnumItemRef" use="/XML/ItemDef/@ID" />

<xsl:template match="XML">
    <xsl:copy>
        <xsl:apply-templates />
        <xsl:call-template name="Items" />
        <xsl:call-template name="ItemDef" />
    </xsl:copy>
</xsl:template>

<xsl:template name="Items">
        <xsl:element name="Items">
        <xsl:for-each select="exslt:node-set($Items)/Item">
            <xsl:element name="ItemRef">
                <xsl:attribute name="ID"><xsl:value-of select="text()"/></xsl:attribute>
            </xsl:element>
        </xsl:for-each>
    </xsl:element>
</xsl:template>

<xsl:template name="ItemDef">
    <xsl:for-each select="exslt:node-set($Items)/Item">
        <xsl:element name="ItemDef">
            <xsl:attribute name="ID"><xsl:value-of select="text()" /></xsl:attribute>
        </xsl:element>
        <-- how can I find the corresponding EnumitemRef and EnumItem? -->
        <xsl:copy-of select="key('get_Enum_by_ID', @ID)" /> 

    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

如果有人可以给我一个解决方案的想法,我将非常高兴。

尽管这并不简单,但我认为您正在使它变得比所需复杂得多。 尝试使用以下样式表(未经充分测试):

XSLT 1.0

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">

<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:variable name="Items">
    <Item ID="answer">newid_answer</Item>
    <Item ID="number">newid_number</Item>
</xsl:variable>

<xsl:key name="ItemDef-by-ID" match="ItemDef" use="@ID"/>
<xsl:key name="EnumItem-by-EID" match="EnumItem" use="@EID"/>

<xsl:variable name="xml" select="/"/>

<xsl:template match="/XML">
    <xsl:copy>
        <Items>
            <xsl:copy-of select="$Items" /> 
        </Items>
        <xsl:apply-templates select="exsl:node-set($Items)/Item"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Item">
    <xsl:variable name="item-id" select="@ID"/>

    <xsl:variable name="EnumItemRef">
        <xsl:for-each select="$xml">
            <xsl:copy-of select="key('ItemDef-by-ID', $item-id)/EnumItemRef"/>
        </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="EID" select="exsl:node-set($EnumItemRef)/EnumItemRef/@EID"/>

    <ItemDef ID="{.}">
        <xsl:copy-of select="$EnumItemRef"/>
    </ItemDef>
    <xsl:for-each select="$xml">
        <xsl:copy-of select="key('EnumItem-by-EID', $EID)"/>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

注意 :当您处于由exslt:node-set()函数创建的节点集的上下文中时,除非将上下文切换到源文档,否则不能使用key()在源XML文档中查找数据。第一。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM