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_Numbers_Counter - Fatal编程技术网

Xml 当前文档中的XSLT节点计数器

Xml 当前文档中的XSLT节点计数器,xml,xslt,numbers,counter,Xml,Xslt,Numbers,Counter,我有以下xml文档 <root> <TotalPeople>BLABLA</TotalPeople> <MoreTagsWithData/> <Person> <id>bla-bla</id> <Name>John Smith</Name> <MoreTagsWithData/&g

我有以下xml文档

<root>
    <TotalPeople>BLABLA</TotalPeople>
       <MoreTagsWithData/>
       <Person> 
           <id>bla-bla</id>
           <Name>John Smith</Name>
           <MoreTagsWithData/>
       </Person> 
       <Person> 
           <id>bla-bla</id>
           <Name>John Doe</Name>
           <MoreTagsWithData/>
       </Person> 
     </root>

布拉布拉
布拉布拉
约翰·史密斯
布拉布拉
无名氏
我需要拿到文件

 <root>
<TotalPeople>2</TotalPeople> <!-- Needs to calculate how many "Person" tags -->
   <MoreTagsWithData/>
   <Person> 
       <id>1</id>  <!-- incrementing per each Person -->
       <Name>John Smith</Name>
       <MoreTagsWithData/>
   </Person> 
   <Person> 
       <id>2</id>
       <Name>John Doe</Name>
       <MoreTagsWithData/>
   </Person> 
 </root>

2.
1.
约翰·史密斯
2.
无名氏
我尝试了XSLT模板:

<!-- copy all file (I need to save the whole file since in reality it contains much more data -->

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

<!-- indexing ids -->
    <xsl:template match="id">
    <xsl:copy>
                <xsl:number level="any"/>
    </xsl:copy>
 </xsl:template>


<!-- Piece I am not sure , it does not work -->

  <xsl:template match="TotalPeople">
        <xsl:copy>
                <xsl:number level="any" count="/root/Person/id"/>
        </xsl:copy>
  </xsl:template>


我需要计算文档中有多少个标记,并使用此值修改文档中的特殊标记。我无法创建新文档,因为真实文档包含大量信息,我需要对其进行维护

您可以按如下方式更改最后一个模板:

<xsl:template match="TotalPeople">
    <xsl:copy>
        <xsl:value-of select="count(/root/Person/id)"/>
        <!-- or just  select="count(/root/Person)" -->
    </xsl:copy>
</xsl:template>


XSLT样式表旨在将输入XML文档转换为单独的输出文档,而不是就地编辑文档。上述操作将生成您请求的输出文档,但不会修改现有文档。至少,我不知道有哪个XSLT处理器可以做到这一点。相反,您可以删除输入XML文件并重命名输出XML以替换它。

您可以使用下面的样式表之类的东西,将输入XML文档转换为单独的输出文档,如@LarsH said

XSLT1.0

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

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

    <xsl:template match="TotalPeople">
        <xsl:copy>
            <xsl:value-of select="count(../Person)"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="id">
        <xsl:copy>
            <xsl:number count="Person"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

有趣的。。。我没想到你能做到。如果您覆盖输入文档,是否保证在它阅读完原始文档之前不会开始覆盖?@LarsH-我不确定。由于它不是流式传输,我认为在开始处理/覆盖之前,必须读取整个输入并将其存储在内存中。我只做了两次,这两次都是针对堆栈溢出的答案。我在测试时没有遇到任何问题,但数据集很小。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:param name="dir" select="'C:/Path/To/Doc'"/>
    <xsl:param name="file" select="'input.xml'"/>

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

    <xsl:template match="/">
        <xsl:for-each select="collection(concat('file:///',$dir,'?select=',$file))">
            <xsl:result-document href="{document-uri(current())}">
                <xsl:apply-templates/>
            </xsl:result-document>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="TotalPeople">
        <xsl:copy>
            <xsl:value-of select="count(../Person)"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="id">
        <xsl:copy>
            <xsl:number count="Person"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>