Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.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_Csv_Xslt - Fatal编程技术网

Xml xslt选择具有可传递依赖关系的节点

Xml xslt选择具有可传递依赖关系的节点,xml,csv,xslt,Xml,Csv,Xslt,在使用xslt将xml转换为csv时,我面临着处理可传递依赖关系的挑战。 以下是我的xml简化版: <root> <hold id="H_100"> <value1>A</value1> </hold> <hold id="H_200"> <value1>B</value1> </hold> <hold id="

在使用xslt将xml转换为csv时,我面临着处理可传递依赖关系的挑战。 以下是我的xml简化版:

<root>
    <hold id="H_100">
        <value1>A</value1>
    </hold>
    <hold id="H_200">
        <value1>B</value1>
    </hold>
    <hold id="H_300">
        <value1>C</value1>
    </hold>
    <party id="C_100">
        <value2>D</value2>
    </party>
    <party id="C_200">
        <value2>E</value2>
    </party>
    <party id="C_300">
        <value2>F</value2>
    </party>
    <party id="A_100">
        <value2>G</value2>
    </party>
    <party id="A_300">
        <value2>H</value2>
    </party>
    <relation hid="H100" pid="C_100"/>
    <relation hid="H100" pid="A_100"/>
    <relation hid="H200" pid="C_200"/> 
    <relation hid="H300" pid="A_300"/> 
</root>

有人知道如何使用xslt来实现这一点吗?

要遵循xslt中的交叉引用,您可以使用键,以便使用xslt 2或3

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

  <xsl:output method="text"/>

  <xsl:key name="rel" match="relation" use="@hid"/>
  <xsl:key name="party" match="party" use="@id"/>

  <xsl:template match="/">
      <xsl:text>Hold,Party&#10;</xsl:text>
      <xsl:apply-templates select="root/hold"/>
  </xsl:template>

  <xsl:template match="hold">
      <xsl:value-of select="value1, key('party', key('rel', translate(@id, '_', ''))/@pid[starts-with(., 'A_')])/value2" separator=","/>
      <xsl:text>&#10;</xsl:text>
  </xsl:template>


</xsl:stylesheet>
对于XSLT 1,您可以使用相同的键,但作为仅输出单个节点的值,您需要将上面使用的值拆分为两个,以输出值1加上引用的值2


如果在实际数据中hid值带有下划线,则可以简化子表达式键'rel',translate@id,至键'rel',@id,请参阅。上面的示例假定hid和id值不同,因此在使用键之前尝试删除下划线。

使用XSLT 1.0尝试如下:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="text" encoding="utf-8"/>
<xsl:template match="/">
    <xsl:value-of select="concat('Hold', ',', 'Party', '&#xA;')"/>
    <xsl:for-each select="/root/*[name() = 'hold']">
        <xsl:variable name="var.hid" select="translate(@id, '_', '')"/>
        <xsl:variable name="var.pid" select="/root/relation[@hid = $var.hid and starts-with(@pid, 'A_')]/@pid"/>
        <xsl:value-of select="concat(value1, ',', /root/party[@id = $var.pid]/value2, '&#xA;')"/>        
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

这些关系/@hid值(如H100)是否指hold/@id值(如H_100)?您发布的代码段中是否缺少hid值的下划线,或者在尝试建立交叉引用时XSLT必须添加下划线?是,代码段中缺少下划线。是的,它们是通过关系元素联系在一起的。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="text" encoding="utf-8"/>
<xsl:template match="/">
    <xsl:value-of select="concat('Hold', ',', 'Party', '&#xA;')"/>
    <xsl:for-each select="/root/*[name() = 'hold']">
        <xsl:variable name="var.hid" select="translate(@id, '_', '')"/>
        <xsl:variable name="var.pid" select="/root/relation[@hid = $var.hid and starts-with(@pid, 'A_')]/@pid"/>
        <xsl:value-of select="concat(value1, ',', /root/party[@id = $var.pid]/value2, '&#xA;')"/>        
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Hold,Party
A,G
B,
C,H