Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.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 Xsl:父节点和属性节点的编号_Xml_Xslt_Xpath - Fatal编程技术网

Xml Xsl:父节点和属性节点的编号

Xml Xsl:父节点和属性节点的编号,xml,xslt,xpath,Xml,Xslt,Xpath,前任职位- 感谢Martin,我正在完成基于相同代码的后续项目。在这个项目中,我需要能够增加父节点的数量,以基于原始节点创建某种关系的xml输出。我还需要为属性创建与当前节点相关的关系 预期结果摘要 将所有节点列为已完成 a) 将所有父节点列为子关系的ID字段- 完成 b) 将所有子节点(没有子节点的最低级别节点)列为已完成 c) 将所有属性列为: i) 如果不存在子节点-无法 为父节点拉### ii)如果存在子节点-无法为父节点拉#### 输入xml: <xml> &l

前任职位-

感谢Martin,我正在完成基于相同代码的后续项目。在这个项目中,我需要能够增加父节点的数量,以基于原始节点创建某种关系的xml输出。我还需要为属性创建与当前节点相关的关系

预期结果摘要

  • 将所有节点列为已完成
  • a) 将所有父节点列为子关系的ID字段- 完成
  • b) 将所有子节点(没有子节点的最低级别节点)列为已完成
  • c) 将所有属性列为:
  • i) 如果不存在子节点-无法 为父节点拉###
  • ii)如果存在子节点-无法为父节点拉####
输入xml:

<xml>
    <individual attr="test" attr2="test3" attr3="test2">
        <name>
            <firstname seq="1">Me</firstname>
            <lastname>Last</lastname>
        </name>
        <addresses>
            <address>
                <street>1234 Main</street>
                <city>Anytown</city>
                <state>TX</state>
            </address>
            <address>
                <street>4321 Central Ave</street>
                <city>Bixby</city>
                <state>ND</state>
            </address>
        </addresses>
        <employeers>
            <employeer>
                <name>
                    <firstname seq3="99">Employer1</firstname>
                    <lastname>EmployerLast</lastname>
                </name>
                <addresses>
                    <address>
                        <street>1234 Employer1</street>
                        <city>Smallville</city>
                        <state>CT</state>
                    </address>
                </addresses>
            </employeer>
            <employeer attr="test" attr2="test3" attr3="test2">
                <name>
                    <firstname>Employer2</firstname>
                    <lastname>EmployerLast2</lastname>
                </name>
                <addresses>
                    <address>
                        <street>1234 Employer2</street>
                        <city>Nashville</city>
                        <state>TN</state>
                    </address>
                </addresses>
            </employeer>
        </employeers>
    </individual>
</xml>

我
最后

实际结果与预期结果:

<?xml version="1.0" encoding="utf-16"?>
<KEY name="individual_001_ParentID" value="xml_001" />
<KEY name="individual_001_attr" value="test" />
<KEY name="individual_001_attr2" value="test3" />
<KEY name="individual_001_attr3" value="test2" />
<KEY name="name_001_ParentID" value="individual_001" />
<KEY name="name_001_firstname" value="Me" />
<KEY name="name_001_firstname_seq" value="1" />
<KEY name="name_001_lastname" value="Last" />
<KEY name="addresses_001_ParentID" value="individual_001" />
<KEY name="address_001_ParentID" value="addresses_001" />
<KEY name="address_001_street" value="1234 Main" />
<KEY name="address_001_city" value="Anytown" />
<KEY name="address_001_state" value="TX" />
<KEY name="address_002_ParentID" value="addresses_002" />
<KEY name="address_002_street" value="4321 Central Ave" />
<KEY name="address_002_city" value="Bixby" />
<KEY name="address_002_state" value="ND" />
<KEY name="employeers_001_ParentID" value="individual_001" />
<KEY name="employeer_001_ParentID" value="employeers_001" />
<KEY name="name_002_ParentID" value="employeer_002" />
<KEY name="name_002_firstname" value="Employer1" />
<!-- actual result -->
<KEY name="name_001_firstname_seq3" value="99" />
<!-- desired result as this is the secod occurrance of the parent node-->
<KEY name="name_002_firstname_seq3" value="99" />
<KEY name="name_002_lastname" value="EmployerLast" />
<KEY name="addresses_002_ParentID" value="employeer_002" />
<KEY name="address_003_ParentID" value="addresses_003" />
<KEY name="address_003_street" value="1234 Employer1" />
<KEY name="address_003_city" value="Smallville" />
<KEY name="address_003_state" value="CT" />
<KEY name="employeer_002_ParentID" value="employeers_002" />
<!-- actual result -->
<KEY name="employeer_001_attr" value="test" />
<KEY name="employeer_001_attr2" value="test3" />
<KEY name="employeer_001_attr3" value="test2" />
<!-- desired result as this is the secod occurrance of the parent node-->
<KEY name="employeer_002_attr" value="test" />
<KEY name="employeer_002_attr2" value="test3" />
<KEY name="employeer_002_attr3" value="test2" />
<KEY name="name_003_ParentID" value="employeer_003" />
<KEY name="name_003_firstname" value="Employer2" />
<KEY name="name_003_lastname" value="EmployerLast2" />
<KEY name="addresses_003_ParentID" value="employeer_003" />
<KEY name="address_004_ParentID" value="addresses_004" />
<KEY name="address_004_street" value="1234 Employer2" />
<KEY name="address_004_city" value="Nashville" />
<KEY name="address_004_state" value="TN" />

如果我们将编号保存在变量中,例如

<xsl:variable name="first_count">
    <xsl:number format="001" level="any"/>
</xsl:variable>
我们可以达到你想要的结果。修改后的样式表如下所示:

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

    <xsl:template match="/*//*[*]">
        <xsl:variable name="first_count">
            <xsl:number format="001" level="any"/>
        </xsl:variable>
        <xsl:element name="KEY">
            <xsl:attribute name="name">
                <xsl:value-of select="local-name()"/>_<xsl:value-of select="$first_count"/>_ParentID</xsl:attribute>
            <xsl:attribute name="value">
                <xsl:value-of select="name(..)"/>_<xsl:value-of select="$first_count"/>
            </xsl:attribute>
        </xsl:element>
        <xsl:for-each select="@*">
            <xsl:element name="KEY">
                <!-- Trying to get the output to list:
                    1) the current node and increment - issue
                    2) the current attribute -->
                <xsl:attribute name="name">
                    <xsl:value-of select="name(..)"/>_<xsl:value-of select="$first_count"/>_<xsl:value-of select="name()"/>
                </xsl:attribute>
                <xsl:attribute name="value">
                    <xsl:value-of select="."/>
                </xsl:attribute>
            </xsl:element>
        </xsl:for-each>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="//*[not(*)]">
        <xsl:variable name="second_count">
            <xsl:number format="001" level="any"/>
        </xsl:variable>
        <xsl:element name="KEY">
            <!-- Trying to get the output to list:
                1) the parent node and increment - issue
                2) the current node -->
            <xsl:attribute name="name">
                <xsl:value-of select="name(..)"/>_<xsl:value-of select="$second_count"/>_<xsl:value-of select="local-name()"/>
            </xsl:attribute>
            <xsl:attribute name="value">
                <xsl:value-of select="current()"/>
            </xsl:attribute>
        </xsl:element>
        <xsl:for-each select="@*">
            <xsl:element name="KEY">
                <!-- Trying to get the output to list:
                    1) the parent node and increment - issue
                    2) the current node
                    3) the current attribute -->
                <xsl:attribute name="name">
                    <xsl:value-of select="name(../..)"/>_<xsl:value-of select="$second_count"/>_<xsl:value-of select="name(..)"/>_<xsl:value-of select="name()"/>
                </xsl:attribute>
                <xsl:attribute name="value">
                    <xsl:value-of select="."/>
                </xsl:attribute>
            </xsl:element>
        </xsl:for-each>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="text()"/>
</xsl:stylesheet>

__父ID
_
__
__
___

如果我们将编号保存在变量中,如

<xsl:variable name="first_count">
    <xsl:number format="001" level="any"/>
</xsl:variable>
我们可以达到你想要的结果。修改后的样式表如下所示:

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

    <xsl:template match="/*//*[*]">
        <xsl:variable name="first_count">
            <xsl:number format="001" level="any"/>
        </xsl:variable>
        <xsl:element name="KEY">
            <xsl:attribute name="name">
                <xsl:value-of select="local-name()"/>_<xsl:value-of select="$first_count"/>_ParentID</xsl:attribute>
            <xsl:attribute name="value">
                <xsl:value-of select="name(..)"/>_<xsl:value-of select="$first_count"/>
            </xsl:attribute>
        </xsl:element>
        <xsl:for-each select="@*">
            <xsl:element name="KEY">
                <!-- Trying to get the output to list:
                    1) the current node and increment - issue
                    2) the current attribute -->
                <xsl:attribute name="name">
                    <xsl:value-of select="name(..)"/>_<xsl:value-of select="$first_count"/>_<xsl:value-of select="name()"/>
                </xsl:attribute>
                <xsl:attribute name="value">
                    <xsl:value-of select="."/>
                </xsl:attribute>
            </xsl:element>
        </xsl:for-each>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="//*[not(*)]">
        <xsl:variable name="second_count">
            <xsl:number format="001" level="any"/>
        </xsl:variable>
        <xsl:element name="KEY">
            <!-- Trying to get the output to list:
                1) the parent node and increment - issue
                2) the current node -->
            <xsl:attribute name="name">
                <xsl:value-of select="name(..)"/>_<xsl:value-of select="$second_count"/>_<xsl:value-of select="local-name()"/>
            </xsl:attribute>
            <xsl:attribute name="value">
                <xsl:value-of select="current()"/>
            </xsl:attribute>
        </xsl:element>
        <xsl:for-each select="@*">
            <xsl:element name="KEY">
                <!-- Trying to get the output to list:
                    1) the parent node and increment - issue
                    2) the current node
                    3) the current attribute -->
                <xsl:attribute name="name">
                    <xsl:value-of select="name(../..)"/>_<xsl:value-of select="$second_count"/>_<xsl:value-of select="name(..)"/>_<xsl:value-of select="name()"/>
                </xsl:attribute>
                <xsl:attribute name="value">
                    <xsl:value-of select="."/>
                </xsl:attribute>
            </xsl:element>
        </xsl:for-each>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="text()"/>
</xsl:stylesheet>

__父ID
_
__
__
___

至少在XSLT 2或3中,您还可以将编号更改为,例如

            <xsl:attribute name="name">
                <xsl:value-of select="name(..)"/>_<xsl:number format="001" select=".." level="any"/>_<xsl:value-of select="name()"/>
            </xsl:attribute>

__
要计算属性的父元素,请参见


至少在XSLT 2或3中,您还可以将编号更改为,例如

            <xsl:attribute name="name">
                <xsl:value-of select="name(..)"/>_<xsl:number format="001" select=".." level="any"/>_<xsl:value-of select="name()"/>
            </xsl:attribute>

__
要计算属性的父元素,请参见


我认为,通过在变量中捕获名称/编号,并将其作为参数传递到应用模板中,可以稍微简化样式表

您还应该能够对没有子元素的所有属性和元素使用单个模板

似乎也没有理由使用
xsl:element
而不是创建文本结果元素

我一直在使用
local-name()
。如果需要包含任何名称空间前缀,请改用
name()

我还使用了XSLT2.0,因为它是样式表中指定的版本。在下面的示例链接中,我将引擎改为Saxon HE,而不是MS XslCompiledTransform(1.0处理器)

XSLT2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/*" priority="1">
    <xsl:apply-templates select="@*|*"/>
  </xsl:template>

  <xsl:template match="*">
    <xsl:param name="parentInfo"/>
    <xsl:variable name="nbr">
      <xsl:number format="000" level="any"/>
    </xsl:variable>
    <xsl:variable name="parentNbr">
      <xsl:number format="000" level="any" select=".."/>
    </xsl:variable>
    <KEY
      name="{string-join((local-name(),$nbr,'ParentID'),'_')}"
      value="{string-join((local-name(..),$parentNbr),'_')}"/>
    <xsl:apply-templates select="@*,*">
      <xsl:with-param name="parentInfo" 
        select="string-join((local-name(),$nbr),'_')"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="@*|*[not(*)]">
    <xsl:param name="parentInfo"/>
    <KEY
      name="{string-join((
      if (self::attribute() and not(../../*[*])) then 
      ($parentInfo,local-name(..)) else $parentInfo,
      local-name()),'_')}"
      value="{.}"
    />
    <xsl:apply-templates select="@*">
      <xsl:with-param name="parentInfo" select="$parentInfo"/>
    </xsl:apply-templates>
  </xsl:template>

</xsl:stylesheet>

输出

<KEY name="individual_001_ParentID" value="xml_001"/>
<KEY name="individual_001_attr" value="test"/>
<KEY name="individual_001_attr2" value="test3"/>
<KEY name="individual_001_attr3" value="test2"/>
<KEY name="name_001_ParentID" value="individual_001"/>
<KEY name="name_001_firstname" value="Me"/>
<KEY name="name_001_firstname_seq" value="1"/>
<KEY name="name_001_lastname" value="Last"/>
<KEY name="addresses_001_ParentID" value="individual_001"/>
<KEY name="address_001_ParentID" value="addresses_001"/>
<KEY name="address_001_street" value="1234 Main"/>
<KEY name="address_001_city" value="Anytown"/>
<KEY name="address_001_state" value="TX"/>
<KEY name="address_002_ParentID" value="addresses_001"/>
<KEY name="address_002_street" value="4321 Central Ave"/>
<KEY name="address_002_city" value="Bixby"/>
<KEY name="address_002_state" value="ND"/>
<KEY name="employeers_001_ParentID" value="individual_001"/>
<KEY name="employeer_001_ParentID" value="employeers_001"/>
<KEY name="name_002_ParentID" value="employeer_001"/>
<KEY name="name_002_firstname" value="Employer1"/>
<KEY name="name_002_firstname_seq3" value="99"/>
<KEY name="name_002_lastname" value="EmployerLast"/>
<KEY name="addresses_002_ParentID" value="employeer_001"/>
<KEY name="address_003_ParentID" value="addresses_002"/>
<KEY name="address_003_street" value="1234 Employer1"/>
<KEY name="address_003_city" value="Smallville"/>
<KEY name="address_003_state" value="CT"/>
<KEY name="employeer_002_ParentID" value="employeers_001"/>
<KEY name="employeer_002_attr" value="test"/>
<KEY name="employeer_002_attr2" value="test3"/>
<KEY name="employeer_002_attr3" value="test2"/>
<KEY name="name_003_ParentID" value="employeer_002"/>
<KEY name="name_003_firstname" value="Employer2"/>
<KEY name="name_003_lastname" value="EmployerLast2"/>
<KEY name="addresses_003_ParentID" value="employeer_002"/>
<KEY name="address_004_ParentID" value="addresses_003"/>
<KEY name="address_004_street" value="1234 Employer2"/>
<KEY name="address_004_city" value="Nashville"/>
<KEY name="address_004_state" value="TN"/>

工作实例:


我认为,通过在变量中捕获名称/编号,并将其作为参数传递到应用模板中,可以稍微简化样式表

您还应该能够对没有子元素的所有属性和元素使用单个模板

似乎也没有理由使用
xsl:element
而不是创建文本结果元素

我一直在使用
local-name()
。如果需要包含任何名称空间前缀,请改用
name()

我还使用了XSLT2.0,因为它是样式表中指定的版本。在下面的示例链接中,我将引擎改为Saxon HE,而不是MS XslCompiledTransform(1.0处理器)

XSLT2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/*" priority="1">
    <xsl:apply-templates select="@*|*"/>
  </xsl:template>

  <xsl:template match="*">
    <xsl:param name="parentInfo"/>
    <xsl:variable name="nbr">
      <xsl:number format="000" level="any"/>
    </xsl:variable>
    <xsl:variable name="parentNbr">
      <xsl:number format="000" level="any" select=".."/>
    </xsl:variable>
    <KEY
      name="{string-join((local-name(),$nbr,'ParentID'),'_')}"
      value="{string-join((local-name(..),$parentNbr),'_')}"/>
    <xsl:apply-templates select="@*,*">
      <xsl:with-param name="parentInfo" 
        select="string-join((local-name(),$nbr),'_')"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="@*|*[not(*)]">
    <xsl:param name="parentInfo"/>
    <KEY
      name="{string-join((
      if (self::attribute() and not(../../*[*])) then 
      ($parentInfo,local-name(..)) else $parentInfo,
      local-name()),'_')}"
      value="{.}"
    />
    <xsl:apply-templates select="@*">
      <xsl:with-param name="parentInfo" select="$parentInfo"/>
    </xsl:apply-templates>
  </xsl:template>

</xsl:stylesheet>

输出

<KEY name="individual_001_ParentID" value="xml_001"/>
<KEY name="individual_001_attr" value="test"/>
<KEY name="individual_001_attr2" value="test3"/>
<KEY name="individual_001_attr3" value="test2"/>
<KEY name="name_001_ParentID" value="individual_001"/>
<KEY name="name_001_firstname" value="Me"/>
<KEY name="name_001_firstname_seq" value="1"/>
<KEY name="name_001_lastname" value="Last"/>
<KEY name="addresses_001_ParentID" value="individual_001"/>
<KEY name="address_001_ParentID" value="addresses_001"/>
<KEY name="address_001_street" value="1234 Main"/>
<KEY name="address_001_city" value="Anytown"/>
<KEY name="address_001_state" value="TX"/>
<KEY name="address_002_ParentID" value="addresses_001"/>
<KEY name="address_002_street" value="4321 Central Ave"/>
<KEY name="address_002_city" value="Bixby"/>
<KEY name="address_002_state" value="ND"/>
<KEY name="employeers_001_ParentID" value="individual_001"/>
<KEY name="employeer_001_ParentID" value="employeers_001"/>
<KEY name="name_002_ParentID" value="employeer_001"/>
<KEY name="name_002_firstname" value="Employer1"/>
<KEY name="name_002_firstname_seq3" value="99"/>
<KEY name="name_002_lastname" value="EmployerLast"/>
<KEY name="addresses_002_ParentID" value="employeer_001"/>
<KEY name="address_003_ParentID" value="addresses_002"/>
<KEY name="address_003_street" value="1234 Employer1"/>
<KEY name="address_003_city" value="Smallville"/>
<KEY name="address_003_state" value="CT"/>
<KEY name="employeer_002_ParentID" value="employeers_001"/>
<KEY name="employeer_002_attr" value="test"/>
<KEY name="employeer_002_attr2" value="test3"/>
<KEY name="employeer_002_attr3" value="test2"/>
<KEY name="name_003_ParentID" value="employeer_002"/>
<KEY name="name_003_firstname" value="Employer2"/>
<KEY name="name_003_lastname" value="EmployerLast2"/>
<KEY name="addresses_003_ParentID" value="employeer_002"/>
<KEY name="address_004_ParentID" value="addresses_003"/>
<KEY name="address_004_street" value="1234 Employer2"/>
<KEY name="address_004_city" value="Nashville"/>
<KEY name="address_004_state" value="TN"/>

工作实例:


考虑将所需输出添加到问题中。添加的实际结果与所需结果考虑将所需输出添加到问题中。添加的实际结果与所需结果虽然在有限的示例中有效,但在我的实际数据中不起作用,如最后4行所示。所有这些都应该是关于_VERSION _002而不是001的。虽然这在有限的示例中有效,但在我的实际数据中不起作用,如最后4行所示。所有这些都应该是关于_VERSION _002而不是001的。虽然这在有限的示例中有效,但在我的实际数据中不起作用,如最后4行所示。所有这些都应该是关于_VERSION _002而不是001的。虽然这在有限的示例中有效,但在我的实际数据中不起作用,如最后4行所示。所有这些都应该是关于_版本_002而不是001的。谢谢您的简化。现在