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
如何使用XSLT1.0替换XML文件中的ID元素及其所有引用元素_Xml_Xslt_Xslt 1.0 - Fatal编程技术网

如何使用XSLT1.0替换XML文件中的ID元素及其所有引用元素

如何使用XSLT1.0替换XML文件中的ID元素及其所有引用元素,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我需要仅使用XSLT缩短XML文档中的一些ID值及其引用 XML文档示例: <root> <firstChild> <ID>99999</ID> </firstChild> <secondChild> <IDRef>99999</IDRef> </secondChild> <thirdChild> <person> <IDRef&g

我需要仅使用XSLT缩短XML文档中的一些ID值及其引用

XML文档示例:

<root>
 <firstChild>
  <ID>99999</ID>
 </firstChild>
 <secondChild>
  <IDRef>99999</IDRef>
 </secondChild>
 <thirdChild>
  <person>
   <IDRef>99999</IDRef>
  </person>
 </thirdChild>
</root>

99999
99999
99999
应用XSLT后的预期结果:

<root>
 <firstChild>
  <ID>1</ID>
 </firstChild>
 <secondChild>
  <IDRef>1</IDRef>
 </secondChild>
 <thirdChild>
  <person>
   <IDRef>1</IDRef>
  </person>
 </thirdChild>
</root>

1.
1.
1.
基本上,我需要XSLT找到每个ID标记,用一个值替换它,然后在文档的其他地方找到任何IDRef标记,并用与ID标记相同的标记替换它们

编辑-替换值必须是递增的数字。我认为使其递增的最好方法是使用xslt中的position()函数。例如:

<xsl:variable name="ReplacementID" Select="position()"/>

我不太关心如何在这个阶段使数字增加,我更关心如何(如果可能的话): 1.匹配ID标记,将其文本节点更改为新值, 2.然后匹配任何IDRef节点,并将其文本替换为与步骤1中添加到ID标记的值相同的值 值本身可以是从全局变量到传递到样式表中的参数的任何内容

下面是我尝试做的一个非常粗略的XSLT(它不起作用)


1.
那么:

<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:strip-space elements="*"/>

<xsl:key name="id" match="ID" use="." />

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

<xsl:template match="ID">
    <xsl:copy>
        <xsl:value-of select="count(preceding::ID) + 1" />
    </xsl:copy>
</xsl:template>

<xsl:template match="IDRef">
    <xsl:copy>
        <xsl:value-of select="count(key('id', .)/preceding::ID) + 1" />
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

应用于以下测试输入:

<root>
    <master>
        <ID>12345</ID>
    </master>
    <slave>
        <IDRef>12345</IDRef>
    </slave>
    <element>
        <slave>
            <IDRef>987</IDRef>
        </slave>
    </element>
    <master>
        <ID>987</ID>
    </master>
    <slave>
        <IDRef>987</IDRef>
    </slave>
    <element>
        <slave>
            <IDRef>12345</IDRef>
        </slave>
    </element>
</root>

12345
12345
987
987
987
12345
结果是:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <master>
      <ID>1</ID>
   </master>
   <slave>
      <IDRef>1</IDRef>
   </slave>
   <element>
      <slave>
         <IDRef>2</IDRef>
      </slave>
   </element>
   <master>
      <ID>2</ID>
   </master>
   <slave>
      <IDRef>2</IDRef>
   </slave>
   <element>
      <slave>
         <IDRef>1</IDRef>
      </slave>
   </element>
</root>

1.
1.
2.
2.
2.
1.
--
顺便说一句,我不太明白缩短ID值的目的是什么;只要它们是独一无二的,谁在乎它们有多长


我更关心的是如何(如果可能的话):1。匹配ID 标记,将其文本节点更改为新值2。然后匹配任何IDRef 节点,并将其文本替换为与所添加内容相同的值 步骤1中的ID标记


这实际上取决于第一步的具体执行方式。因为IDRef始终可以访问源文档中的原始ID元素,但不能访问结果树中转换后的对应项。

问题不清楚:您是如何从“99999”到“1”的?我还建议扩展您的示例,以包括至少两个不同ID值的实例。抱歉,是的,它有点模糊。让我添加一些详细信息。编辑完成后,希望这更合理。这看起来正是我想要的!另外-不幸的是,付钱给我的人要求缩短ID:P@StevenP哈哈,我希望我能为此得到报酬…——请注意我在答案末尾添加的注释。我刚刚将此解决方案推到了极限,效果非常好!做得好,您是XSLT专家!
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <master>
      <ID>1</ID>
   </master>
   <slave>
      <IDRef>1</IDRef>
   </slave>
   <element>
      <slave>
         <IDRef>2</IDRef>
      </slave>
   </element>
   <master>
      <ID>2</ID>
   </master>
   <slave>
      <IDRef>2</IDRef>
   </slave>
   <element>
      <slave>
         <IDRef>1</IDRef>
      </slave>
   </element>
</root>