如何为父子孙元素分配一个唯一的 id?
How to assign a unique id to the Parent, child and grandchild element?
我是 xslt 的新手,如果有人能帮助我解决这个问题,那将非常有帮助。
我有一个 XML 文档,看起来像这样,
<ParentElement>
<ChildElement name = "xxx" place = "yyy">
<GrandChildElement parameter1 = "a" parameter2 = "b">
</GrandchildElement>
<GrandChildElement parameter1 = "c" parameter2 = "d">
</GrandchildElement>
</ChildElement>
<ChildElement name = "xxx" place = "yyy">
<GrandChildElement parameter1 = "a" parameter2 = "x">
</GrandchildElement>
<GrandChildElement parameter1 = "c" parameter2 = "y">
</GrandchildElement>
</ChildElement>
</ParentElement>
我想为每个子元素和每个孙元素分配一个唯一的 ID。我想要的输出应该是这样的,
<ParentElement>
<ChildElement>
<Child_ID>100</Child_ID>
<Name></Name>
<GrandChild>
<id>200</id>
<Label></Label>
</GrandChild>
<GrandChild>
<id>201</id>
<Label></Label>
</GrandChild>
<GrandChild>
<id>202</id>
<Label></Label>
</GrandChild>
</ChildElement>
<ChildElement>
<Child_ID>101</Child_ID>
<Name></Name>
<GrandChild>
<id>203</id>
<Label></Label>
</GrandChild>
<GrandChild>
<id>204</id>
<Label></Label>
</GrandChild>
</ChildElement>
</ParentElement>
我使用它为成功的子元素创建了 id。
<xsl:for-each select="ChildElement">
<xsl:variable name="i" select="1" />
<xsl:variable name="j" select="$i + position()"/>
<xsl:element name = "ChildElement">
<xsl:element name = "Id">DT-<xsl:value-of select="200 + $j"/></xsl:element>
</xsl:for-each>
如何为每个孙子获得不同的 ID?
XSLT 具有为输入中的每个节点生成唯一 ID 的内置函数 XML。考虑以下示例:
XML
<ParentElement>
<ChildElement name = "xxx" place = "yyy">
<GrandChildElement parameter1 = "a" parameter2 = "b"/>
<GrandChildElement parameter1 = "c" parameter2 = "d"/>
</ChildElement>
<ChildElement name = "xxx" place = "yyy">
<GrandChildElement parameter1 = "a" parameter2 = "x"/>
<GrandChildElement parameter1 = "c" parameter2 = "y"/>
</ChildElement>
</ParentElement>
XSLT 1.0
<xsl:stylesheet version="1.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="ParentElement">
<xsl:copy>
<xsl:for-each select="ChildElement">
<xsl:copy>
<Child_ID>
<xsl:value-of select="generate-id()"/>
</Child_ID>
<xsl:for-each select="GrandChildElement">
<GrandChild>
<id>
<xsl:value-of select="generate-id()"/>
</id>
</GrandChild>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
确切的结果因处理器而异。例如,libxslt
可能 return 结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<ParentElement>
<ChildElement>
<Child_ID>idm49868912656</Child_ID>
<GrandChild>
<id>idm49868912048</id>
</GrandChild>
<GrandChild>
<id>idm49868911344</id>
</GrandChild>
</ChildElement>
<ChildElement>
<Child_ID>idm49868910448</Child_ID>
<GrandChild>
<id>idm49868909744</id>
</GrandChild>
<GrandChild>
<id>idm49868909008</id>
</GrandChild>
</ChildElement>
</ParentElement>
而 Xalan
将产生如下结果:
<?xml version="1.0" encoding="UTF-8"?><ParentElement>
<ChildElement>
<Child_ID>N10004</Child_ID>
<GrandChild>
<id>N10008</id>
</GrandChild>
<GrandChild>
<id>N1000C</id>
</GrandChild>
</ChildElement>
<ChildElement>
<Child_ID>N10011</Child_ID>
<GrandChild>
<id>N10015</id>
</GrandChild>
<GrandChild>
<id>N10019</id>
</GrandChild>
</ChildElement>
</ParentElement>
因此,如果您正在寻找您在输入中显示的模式 XML,这可能是一种方法。您必须考虑当您拥有超过 100 个 ChildElement 元素时会发生什么。只是玩你的抵消。如果你不想在你的 id 中使用字母,这种方法可能会有用。或者您正在处理多个 XML。只需将参数传递给您的 XSLT 文件和您的唯一起始偏移量。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt">
<xsl:output indent="yes"/>
<xsl:variable name="childIDs">
<xsl:for-each select="//ChildElement">
<xsl:element name="element">
<xsl:element name="id">
<xsl:value-of select="generate-id(.)"/>
</xsl:element>
<xsl:element name="outid">
<xsl:value-of select="position() + 100"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:variable>
<!-- For 1.0 use your own prefix here. It may not be msxml. -->
<xsl:variable name="childIDList" select="msxml:node-set($childIDs)"/>
<xsl:variable name="grandchildIDs">
<xsl:for-each select="//GrandChildElement">
<xsl:element name="element">
<xsl:element name="id">
<xsl:value-of select="generate-id(.)"/>
</xsl:element>
<xsl:element name="outid">
<xsl:value-of select="position() + 200"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:variable>
<!-- For 1.0 use your own prefix here. It may not be msxml. -->
<xsl:variable name="grandchildIDList" select="msxml:node-set($grandchildIDs)"/>
<xsl:template match="ChildElement">
<xsl:variable name="id" select="generate-id(.)"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:element name="Child_ID">
<xsl:value-of select="$childIDList/element[id = $id]/outid"/>
</xsl:element>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GrandChildElement">
<xsl:variable name="id" select="generate-id(.)"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:element name="id">
<xsl:value-of select="$grandchildIDList/element[id = $id]/outid"/>
</xsl:element>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我是 xslt 的新手,如果有人能帮助我解决这个问题,那将非常有帮助。 我有一个 XML 文档,看起来像这样,
<ParentElement>
<ChildElement name = "xxx" place = "yyy">
<GrandChildElement parameter1 = "a" parameter2 = "b">
</GrandchildElement>
<GrandChildElement parameter1 = "c" parameter2 = "d">
</GrandchildElement>
</ChildElement>
<ChildElement name = "xxx" place = "yyy">
<GrandChildElement parameter1 = "a" parameter2 = "x">
</GrandchildElement>
<GrandChildElement parameter1 = "c" parameter2 = "y">
</GrandchildElement>
</ChildElement>
</ParentElement>
我想为每个子元素和每个孙元素分配一个唯一的 ID。我想要的输出应该是这样的,
<ParentElement>
<ChildElement>
<Child_ID>100</Child_ID>
<Name></Name>
<GrandChild>
<id>200</id>
<Label></Label>
</GrandChild>
<GrandChild>
<id>201</id>
<Label></Label>
</GrandChild>
<GrandChild>
<id>202</id>
<Label></Label>
</GrandChild>
</ChildElement>
<ChildElement>
<Child_ID>101</Child_ID>
<Name></Name>
<GrandChild>
<id>203</id>
<Label></Label>
</GrandChild>
<GrandChild>
<id>204</id>
<Label></Label>
</GrandChild>
</ChildElement>
</ParentElement>
我使用它为成功的子元素创建了 id。
<xsl:for-each select="ChildElement">
<xsl:variable name="i" select="1" />
<xsl:variable name="j" select="$i + position()"/>
<xsl:element name = "ChildElement">
<xsl:element name = "Id">DT-<xsl:value-of select="200 + $j"/></xsl:element>
</xsl:for-each>
如何为每个孙子获得不同的 ID?
XSLT 具有为输入中的每个节点生成唯一 ID 的内置函数 XML。考虑以下示例:
XML
<ParentElement>
<ChildElement name = "xxx" place = "yyy">
<GrandChildElement parameter1 = "a" parameter2 = "b"/>
<GrandChildElement parameter1 = "c" parameter2 = "d"/>
</ChildElement>
<ChildElement name = "xxx" place = "yyy">
<GrandChildElement parameter1 = "a" parameter2 = "x"/>
<GrandChildElement parameter1 = "c" parameter2 = "y"/>
</ChildElement>
</ParentElement>
XSLT 1.0
<xsl:stylesheet version="1.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="ParentElement">
<xsl:copy>
<xsl:for-each select="ChildElement">
<xsl:copy>
<Child_ID>
<xsl:value-of select="generate-id()"/>
</Child_ID>
<xsl:for-each select="GrandChildElement">
<GrandChild>
<id>
<xsl:value-of select="generate-id()"/>
</id>
</GrandChild>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
确切的结果因处理器而异。例如,libxslt
可能 return 结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<ParentElement>
<ChildElement>
<Child_ID>idm49868912656</Child_ID>
<GrandChild>
<id>idm49868912048</id>
</GrandChild>
<GrandChild>
<id>idm49868911344</id>
</GrandChild>
</ChildElement>
<ChildElement>
<Child_ID>idm49868910448</Child_ID>
<GrandChild>
<id>idm49868909744</id>
</GrandChild>
<GrandChild>
<id>idm49868909008</id>
</GrandChild>
</ChildElement>
</ParentElement>
而 Xalan
将产生如下结果:
<?xml version="1.0" encoding="UTF-8"?><ParentElement>
<ChildElement>
<Child_ID>N10004</Child_ID>
<GrandChild>
<id>N10008</id>
</GrandChild>
<GrandChild>
<id>N1000C</id>
</GrandChild>
</ChildElement>
<ChildElement>
<Child_ID>N10011</Child_ID>
<GrandChild>
<id>N10015</id>
</GrandChild>
<GrandChild>
<id>N10019</id>
</GrandChild>
</ChildElement>
</ParentElement>
因此,如果您正在寻找您在输入中显示的模式 XML,这可能是一种方法。您必须考虑当您拥有超过 100 个 ChildElement 元素时会发生什么。只是玩你的抵消。如果你不想在你的 id 中使用字母,这种方法可能会有用。或者您正在处理多个 XML。只需将参数传递给您的 XSLT 文件和您的唯一起始偏移量。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt">
<xsl:output indent="yes"/>
<xsl:variable name="childIDs">
<xsl:for-each select="//ChildElement">
<xsl:element name="element">
<xsl:element name="id">
<xsl:value-of select="generate-id(.)"/>
</xsl:element>
<xsl:element name="outid">
<xsl:value-of select="position() + 100"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:variable>
<!-- For 1.0 use your own prefix here. It may not be msxml. -->
<xsl:variable name="childIDList" select="msxml:node-set($childIDs)"/>
<xsl:variable name="grandchildIDs">
<xsl:for-each select="//GrandChildElement">
<xsl:element name="element">
<xsl:element name="id">
<xsl:value-of select="generate-id(.)"/>
</xsl:element>
<xsl:element name="outid">
<xsl:value-of select="position() + 200"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:variable>
<!-- For 1.0 use your own prefix here. It may not be msxml. -->
<xsl:variable name="grandchildIDList" select="msxml:node-set($grandchildIDs)"/>
<xsl:template match="ChildElement">
<xsl:variable name="id" select="generate-id(.)"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:element name="Child_ID">
<xsl:value-of select="$childIDList/element[id = $id]/outid"/>
</xsl:element>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GrandChildElement">
<xsl:variable name="id" select="generate-id(.)"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:element name="id">
<xsl:value-of select="$grandchildIDList/element[id = $id]/outid"/>
</xsl:element>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>