Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XML XSLT转换以创建主键和外键之间的关系_Xml_Xslt_Primary Key_Foreign Key Relationship - Fatal编程技术网

XML XSLT转换以创建主键和外键之间的关系

XML XSLT转换以创建主键和外键之间的关系,xml,xslt,primary-key,foreign-key-relationship,Xml,Xslt,Primary Key,Foreign Key Relationship,我想使用xslt(主键PK和外键FK)在xml中创建父元素和子元素之间的关系。源xml如下所示: <root> <Patient> <Fname>John</Fname> <Lname>Doe</Lname> <Record>F00025</Record> <Disease> <Date&

我想使用xslt(主键PK和外键FK)在xml中创建父元素和子元素之间的关系。源xml如下所示:

<root>
    <Patient>
        <Fname>John</Fname>
        <Lname>Doe</Lname>
        <Record>F00025</Record>
        <Disease>
            <Date>3/3/2009</Date>
            <Dcode>D0456</Dcode>
            <Comm>comment</Comm>
            <Medicine>
                <Mcode>M00025</Mcode>
                <Qnt>0.01</Qnt>
                <Unit>l</Unit>
            </Medicine>
        </Disease>
        <Disease>
            <Date>3/15/2009</Date>
            <Dcode>D4415</Dcode>
            <Comm></Comm>
        </Disease>
        <Disease>
            <Date>3/19/2009</Date>
            <Dcode>D0176</Dcode>
            <Comm></Comm>
            <Medicine>
                <Mcode>M00015</Mcode>
                <Qnt>10</Qnt>
                <Unit>ml</Unit>
            </Medicine>
            <Medicine>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Num>803125</Num>
                    <Num>803005</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
    <Patient>
        <Fname>Jayne</Fname>
        <Lname>Joyce</Lname>
        <Record>F00156</Record>
        <Disease>
            <Date>3/18/2009</Date>
            <Dcode>D3266</Dcode>
            <Comm></Comm>
            <Medicine>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Num>803125</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
</root>

约翰
雌鹿
F00025
3/3/2009
D0456
评论
M00025
0.01
L
3/15/2009
D4415
3/19/2009
D0176
M00015
10
毫升
M00006
1.
M
803125
803005
杰恩
乔伊斯
F00156
3/18/2009
D3266
M00006
1.
M
803125
转换后的XML应如下所示:

<root>
    <Patient>
        <Patient_PK>1</Patient_PK>
        <Fname>John</Fname>
        <Lname>Doe</Lname>
        <Record>F00025</Record>
        <Disease>
            <Disease_PK>1</Disease_PK>
            <Patient_FK>1</Patient_FK>
            <Date>3/3/2009</Date>
            <Dcode>D0456</Dcode>
            <Comm>comment</Comm>
            <Medicine>
                <Medicine_PK>1</Medicine_PK>
                <Disease_FK>1</Disease_FK>
                <Mcode>M00025</Mcode>
                <Qnt>0.01</Qnt>
                <Unit>l</Unit>
            </Medicine>
        </Disease>
        <Disease>
            <Disease_PK>2</Disease_PK>
            <Patient_FK>1</Patient_FK>
            <Date>3/15/2009</Date>
            <Dcode>D4415</Dcode>
            <Comm></Comm>
        </Disease>
        <Disease>
            <Disease_PK>3</Disease_PK>
            <Patient_FK>1</Patient_FK>
            <Date>3/19/2009</Date>
            <Dcode>D0176</Dcode>
            <Comm></Comm>
            <Medicine>
                <Medicine_PK>2</Medicine_PK>
                <Disease_FK>3</Disease_FK>
                <Mcode>M00015</Mcode>
                <Qnt>10</Qnt>
                <Unit>ml</Unit>
            </Medicine>
            <Medicine>
                <Medicine_PK>3</Medicine_PK>
                <Disease_FK>3</Disease_FK>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Medicine_FK>3</Medicine_FK>
                    <Num>803125</Num>
                    <Num>803005</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
    <Patient>
        <Patient_PK>2</Patient_PK>
        <Fname>Jayne</Fname>
        <Lname>Joyce</Lname>
        <Record>F00156</Record>
        <Disease>
            <Disease_PK>4</Disease_PK>
            <Patient_FK>2</Patient_FK>
            <Date>3/18/2009</Date>
            <Dcode>D3266</Dcode>
            <Comm></Comm>
            <Medicine>
                <Medicine_PK>4</Medicine_PK>
                <Disease_FK>4</Disease_FK>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Medicine_FK>4</Medicine_FK>
                    <Num>803125</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
</root>

1.
约翰
雌鹿
F00025
1.
1.
3/3/2009
D0456
评论
1.
1.
M00025
0.01
L
2.
1.
3/15/2009
D4415
3.
1.
3/19/2009
D0176
2.
3.
M00015
10
毫升
3.
3.
M00006
1.
M
3.
803125
803005
2.
杰恩
乔伊斯
F00156
4.
2.
3/18/2009
D3266
4.
4.
M00006
1.
M
4.
803125
到目前为止,我只是通过搜索这个网站就做到了这一点,但我对XSLT还不熟悉,所以我感到很困惑。我想我的主键是对的,但问题出在外键上,有点不对劲。是否有更好的方法将创建的主键复制到子元素

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='xml' version='1.0' encoding='UTF-8' indent='yes' />

    <xsl:template match="/ | @* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
    </xsl:template>

    <xsl:template match="Patient">
        <xsl:variable name="PK">
            <xsl:number level="any" count="Patient"/>
        </xsl:variable>

        <xsl:copy>
            <Patient_PK>
                <xsl:value-of select="$PK"/>
            </Patient_PK>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Disease">
        <xsl:variable name="PK">
            <xsl:number level="any" count="Disease"/>
        </xsl:variable>
        <xsl:variable name="FK" 
              select="count(../preceding-sibling::*) + 1"/>

        <xsl:copy>
            <Disease_PK>
                <xsl:value-of select="$PK"/>
            </Disease_PK>
            <Patient_FK>
                <xsl:value-of select="$FK"/>
            </Patient_FK>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Medicine">
        <xsl:variable name="PK">
            <xsl:number level="any" count="Medicine"/>
        </xsl:variable>
        <xsl:variable name="FK" 
              select="count(../preceding-sibling::*) + 1"/>

        <xsl:copy>
            <Medicine_PK>
                <xsl:value-of select="$PK"/>
            </Medicine_PK>
            <Disease_FK>
                <xsl:value-of select="$FK"/>
            </Disease_FK>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Icode">
        <xsl:variable name="PK">
            <xsl:number level="any" count="Icode"/>
        </xsl:variable>
        <xsl:variable name="FK" 
              select="count(../preceding-sibling::*) + 1"/>

        <xsl:copy>
            <Icode_PK>
                <xsl:value-of select="$PK"/>
            </Icode_PK>
            <Medicine_FK>
                <xsl:value-of select="$FK"/>
            </Medicine_FK>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

这里有一个解决方案

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="my:my"
    exclude-result-prefixes="xs my">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vPatients" as="element()*">
     <xsl:for-each-group select="/*/Patient/Record" group-by=".">
      <p k="{position()}">
        <xsl:sequence select="."/>
      </p>
     </xsl:for-each-group>
    </xsl:variable>

    <xsl:variable name="vDiseases" as="element()*">
     <xsl:for-each-group select="/*/Patient/Disease" group-by="Dcode">
      <d k="{position()}">
        <xsl:sequence select="Dcode"/>
      </d>
     </xsl:for-each-group>
    </xsl:variable>

    <xsl:variable name="vMedicines" as="element()*">
     <xsl:for-each-group select="/*/Patient/Disease/Medicine" group-by="Mcode">
      <m k="{position()}">
        <xsl:sequence select="Mcode"/>
      </m>
     </xsl:for-each-group>
    </xsl:variable>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="Patient">
  <Patient>
   <Patient_PK><xsl:sequence select="my:PK($vPatients, Record)"/></Patient_PK>
   <xsl:apply-templates/>
  </Patient>
 </xsl:template>

 <xsl:template match="Disease">
  <Disease>
   <Disease_PK><xsl:sequence select="my:PK($vDiseases, Dcode)"/></Disease_PK>
   <Patient_FK><xsl:sequence select="my:PK($vPatients, ../Record)"/></Patient_FK>
   <xsl:apply-templates/>
  </Disease>
 </xsl:template>

  <xsl:template match="Medicine">
  <Medicine>
   <Medicine_PK><xsl:sequence select="my:PK($vMedicines, Mcode)"/></Medicine_PK>
   <Disease_FK><xsl:sequence select="my:PK($vDiseases, ../Dcode)"/></Disease_FK>
   <xsl:apply-templates/>
  </Medicine>
 </xsl:template>

 <xsl:function name="my:PK" as="xs:string">
  <xsl:param name="pCodes" as="element()*"/>
  <xsl:param name="pThis" as="xs:string"/>

  <xsl:sequence select="$pCodes[*[1] eq $pThis]/@k"/>
 </xsl:function>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<root>
    <Patient>
        <Fname>John</Fname>
        <Lname>Doe</Lname>
        <Record>F00025</Record>
        <Disease>
            <Date>3/3/2009</Date>
            <Dcode>D0456</Dcode>
            <Comm>comment</Comm>
            <Medicine>
                <Mcode>M00025</Mcode>
                <Qnt>0.01</Qnt>
                <Unit>l</Unit>
            </Medicine>
        </Disease>
        <Disease>
            <Date>3/15/2009</Date>
            <Dcode>D4415</Dcode>
            <Comm></Comm>
        </Disease>
        <Disease>
            <Date>3/19/2009</Date>
            <Dcode>D0176</Dcode>
            <Comm></Comm>
            <Medicine>
                <Mcode>M00015</Mcode>
                <Qnt>10</Qnt>
                <Unit>ml</Unit>
            </Medicine>
            <Medicine>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Num>803125</Num>
                    <Num>803005</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
    <Patient>
        <Fname>Jayne</Fname>
        <Lname>Joyce</Lname>
        <Record>F00156</Record>
        <Disease>
            <Date>3/18/2009</Date>
            <Dcode>D3266</Dcode>
            <Comm></Comm>
            <Medicine>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Num>803125</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
</root>
<root>
    <Patient>
      <Patient_PK>1</Patient_PK>
        <Fname>John</Fname>
        <Lname>Doe</Lname>
        <Record>F00025</Record>
        <Disease>
         <Disease_PK>1</Disease_PK>
         <Patient_FK>1</Patient_FK>
            <Date>3/3/2009</Date>
            <Dcode>D0456</Dcode>
            <Comm>comment</Comm>
            <Medicine>
            <Medicine_PK>1</Medicine_PK>
            <Disease_FK>1</Disease_FK>
                <Mcode>M00025</Mcode>
                <Qnt>0.01</Qnt>
                <Unit>l</Unit>
            </Medicine>
        </Disease>
        <Disease>
         <Disease_PK>2</Disease_PK>
         <Patient_FK>1</Patient_FK>
            <Date>3/15/2009</Date>
            <Dcode>D4415</Dcode>
            <Comm/>
        </Disease>
        <Disease>
         <Disease_PK>3</Disease_PK>
         <Patient_FK>1</Patient_FK>
            <Date>3/19/2009</Date>
            <Dcode>D0176</Dcode>
            <Comm/>
            <Medicine>
            <Medicine_PK>2</Medicine_PK>
            <Disease_FK>3</Disease_FK>
                <Mcode>M00015</Mcode>
                <Qnt>10</Qnt>
                <Unit>ml</Unit>
            </Medicine>
            <Medicine>
            <Medicine_PK>3</Medicine_PK>
            <Disease_FK>3</Disease_FK>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Num>803125</Num>
                    <Num>803005</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
    <Patient>
      <Patient_PK>2</Patient_PK>
        <Fname>Jayne</Fname>
        <Lname>Joyce</Lname>
        <Record>F00156</Record>
        <Disease>
         <Disease_PK>4</Disease_PK>
         <Patient_FK>2</Patient_FK>
            <Date>3/18/2009</Date>
            <Dcode>D3266</Dcode>
            <Comm/>
            <Medicine>
            <Medicine_PK>3</Medicine_PK>
            <Disease_FK>4</Disease_FK>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Num>803125</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
</root>

约翰
雌鹿
F00025
3/3/2009
D0456
评论
M00025
0.01
L
3/15/2009
D4415
3/19/2009
D0176
M00015
10
毫升
M00006
1.
M
803125
803005
杰恩
乔伊斯
F00156
3/18/2009
D3266
M00006
1.
M
803125
生成所需的正确结果:

<root>
    <Patient>
        <Fname>John</Fname>
        <Lname>Doe</Lname>
        <Record>F00025</Record>
        <Disease>
            <Date>3/3/2009</Date>
            <Dcode>D0456</Dcode>
            <Comm>comment</Comm>
            <Medicine>
                <Mcode>M00025</Mcode>
                <Qnt>0.01</Qnt>
                <Unit>l</Unit>
            </Medicine>
        </Disease>
        <Disease>
            <Date>3/15/2009</Date>
            <Dcode>D4415</Dcode>
            <Comm></Comm>
        </Disease>
        <Disease>
            <Date>3/19/2009</Date>
            <Dcode>D0176</Dcode>
            <Comm></Comm>
            <Medicine>
                <Mcode>M00015</Mcode>
                <Qnt>10</Qnt>
                <Unit>ml</Unit>
            </Medicine>
            <Medicine>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Num>803125</Num>
                    <Num>803005</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
    <Patient>
        <Fname>Jayne</Fname>
        <Lname>Joyce</Lname>
        <Record>F00156</Record>
        <Disease>
            <Date>3/18/2009</Date>
            <Dcode>D3266</Dcode>
            <Comm></Comm>
            <Medicine>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Num>803125</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
</root>
<root>
    <Patient>
      <Patient_PK>1</Patient_PK>
        <Fname>John</Fname>
        <Lname>Doe</Lname>
        <Record>F00025</Record>
        <Disease>
         <Disease_PK>1</Disease_PK>
         <Patient_FK>1</Patient_FK>
            <Date>3/3/2009</Date>
            <Dcode>D0456</Dcode>
            <Comm>comment</Comm>
            <Medicine>
            <Medicine_PK>1</Medicine_PK>
            <Disease_FK>1</Disease_FK>
                <Mcode>M00025</Mcode>
                <Qnt>0.01</Qnt>
                <Unit>l</Unit>
            </Medicine>
        </Disease>
        <Disease>
         <Disease_PK>2</Disease_PK>
         <Patient_FK>1</Patient_FK>
            <Date>3/15/2009</Date>
            <Dcode>D4415</Dcode>
            <Comm/>
        </Disease>
        <Disease>
         <Disease_PK>3</Disease_PK>
         <Patient_FK>1</Patient_FK>
            <Date>3/19/2009</Date>
            <Dcode>D0176</Dcode>
            <Comm/>
            <Medicine>
            <Medicine_PK>2</Medicine_PK>
            <Disease_FK>3</Disease_FK>
                <Mcode>M00015</Mcode>
                <Qnt>10</Qnt>
                <Unit>ml</Unit>
            </Medicine>
            <Medicine>
            <Medicine_PK>3</Medicine_PK>
            <Disease_FK>3</Disease_FK>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Num>803125</Num>
                    <Num>803005</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
    <Patient>
      <Patient_PK>2</Patient_PK>
        <Fname>Jayne</Fname>
        <Lname>Joyce</Lname>
        <Record>F00156</Record>
        <Disease>
         <Disease_PK>4</Disease_PK>
         <Patient_FK>2</Patient_FK>
            <Date>3/18/2009</Date>
            <Dcode>D3266</Dcode>
            <Comm/>
            <Medicine>
            <Medicine_PK>3</Medicine_PK>
            <Disease_FK>4</Disease_FK>
                <Mcode>M00006</Mcode>
                <Qnt>1</Qnt>
                <Unit>m</Unit>
                <Icode>
                    <Num>803125</Num>
                </Icode>
            </Medicine>
        </Disease>
    </Patient>
</root>

1.
约翰
雌鹿
F00025
1.
1.
3/3/2009
D0456
评论
1.
1.
M00025
0.01
L
2.
1.
3/15/2009
D4415
3.
1.
3/19/2009
D0176
2.
3.
M00015
10
毫升
3.
3.
M00006
1.
M
803125
803005
2.
杰恩
乔伊斯
F00156
4.
2.
3/18/2009
D3266
3.
4.
M00006
1.
M
803125

这里有一个解决方案

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="my:my"
    exclude-result-prefixes="xs my">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vPatients" as="element()*">
     <xsl:for-each-group select="/*/Patient/Record" group-by=".">
      <p k="{position()}">
        <xsl:sequence select="."/>
      </p>
     </xsl:for-each-group>
    </xsl:variable>

    <xsl:variable name="vDiseases" as="element()*">
     <xsl:for-each-group select="/*/Patient/Disease" group-by="Dcode">
      <d k="{position()}">
        <xsl:sequence select="Dcode"/>
      </d>
     </xsl:for-each-group>
    </xsl:variable>

    <xsl:variable name="vMedicines" as="element()*">
     <xsl:for-each-group select="/*/Patient/Disease/Medicine" group-by="Mcode">
      <m k="{position()}">
        <xsl:sequence select="Mcode"/>
      </m>
     </xsl:for-each-group>
    </xsl:variable>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="Patient">
  <Patient>
   <Patient_PK><xsl:sequence select="my:PK($vPatients, Record)"/></Patient_PK>
   <xsl:apply-templates/>
  </Patient>
 </xsl:template>

 <xsl:template match="Disease">
  <Disease>
   <Disease_PK><xsl:sequence select="my:PK($vDiseases, Dcode)"/></Disease_PK>
   <Patient_FK><xsl:sequence select="my:PK($vPatients, ../Record)"/></Patient_FK>
   <xsl:apply-templates/>
  </Disease>
 </xsl:template>

  <xsl:template match="Medicine">
  <Medicine>
   <Medicine_PK><xsl:sequence select="my:PK($vMedicines, Mcode)"/></Medicine_PK>
   <Disease_FK><xsl:sequence select="my:PK($vDiseases, ../Dcode)"/></Disease_FK>
   <xsl:apply-templates/>
  </Medicine>
 </xsl:template>

 <xsl:function name="my:PK" as="xs:string">
  <xsl:param name="pCodes" as="element()*"/>
  <xsl:param name="pThis" as="xs:string"/>

  <xsl:sequence select="$pCodes[*[1] eq $pThis]/@k"/>
 </xsl:function>
</xsl:stylesheet>