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

Xml XSLT拆分子节点中的记录,但保留父内容

Xml XSLT拆分子节点中的记录,但保留父内容,xml,xslt,Xml,Xslt,我有一个很大的XML文件,在XML文件中有多个子记录。 我想为每个子记录拆分XML文件,但希望保留父内容,而不触及父内容 下面是我的XML文件的示例 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <DATA> <Account Number='1536764-9'> <T1>testing1</T1> <T2>t

我有一个很大的XML文件,在XML文件中有多个子记录。 我想为每个子记录拆分XML文件,但希望保留父内容,而不触及父内容

下面是我的XML文件的示例

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DATA>
    <Account Number='1536764-9'>
        <T1>testing1</T1>
        <T2>testing2</T2>
        <T3>testing3</T3>
        <T4>testing4</T4>
        <Mobile Number='12345'>
            <InvoiceNo>40800844</InvoiceNo>
            <SO_RC>
                <Code>7679</Code>
                <Description>GPS - Fleet Management Service</Description>
                <Amt>268.00</Amt>
                <PeriodFromDate>01/08/2015</PeriodFromDate>
                <PeriodToDate>31/08/2015</PeriodToDate>
            </SO_RC>
            <TotalSubscriber>268.00</TotalSubscriber>
        </Mobile>
        <Mobile Number='22345'>
            <InvoiceNo>40800844</InvoiceNo>
            <SO_RC>
                <Code>7679</Code>
                <Description>GPS - Fleet Management Service</Description>
                <Amt>268.00</Amt>
                <PeriodFromDate>01/08/2015</PeriodFromDate>
                <PeriodToDate>31/08/2015</PeriodToDate>
            </SO_RC>
            <TotalSubscriber>268.00</TotalSubscriber>
        </Mobile>
        <Mobile Number='32345'>
            <InvoiceNo>40800844</InvoiceNo>
            <SO_RC>
                <Code>7679</Code>
                <Description>GPS - Fleet Management Service</Description>
                <Amt>268.00</Amt>
                <PeriodFromDate>01/08/2015</PeriodFromDate>
                <PeriodToDate>31/08/2015</PeriodToDate>
            </SO_RC>
            <TotalSubscriber>268.00</TotalSubscriber>
        </Mobile>
    </Account>
    <Total_Records>212</Total_Records>
    <Total_Outstanding_Balance>0.00</Total_Outstanding_Balance>
    <Total_Current_Bill_Amt>0.00</Total_Current_Bill_Amt>
</DATA>
我有一些脚本,如下所示,能够拆分出子脚本,但不复制父脚本内容,如下所示

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.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="/">
        <xsl:for-each select="DATA/Account/Mobile">
         <xsl:result-document href="file:///{encode-for-uri('{WATCHTEMPFOLDER}')}{format-number(position(),'000000000')}.xml">
          <DATA>
          <Account>
              <xsl:apply-templates select="."/>
          </Account>
          </DATA>
         </xsl:result-document>
        </xsl:for-each>  
    </xsl:template>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
我不太擅长XSLT,但我想对如何实现所需的XML文件(如下所示)提出一些建议或意见

那么

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  version="2.0"
  exclude-result-prefixes="xs xsi">

<xsl:output indent="yes" encoding="utf-8" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />

<xsl:param name="base-dir" select="'C:\What-ever-directory\'" /> 

<xsl:template match="/">
  <xsl:apply-templates select="DATA/Account/Mobile" />
  <empty xsi:nil="true" />
</xsl:template>

<xsl:template match="Mobile">
  <xsl:variable name="doc-no" as="xs:string">
    <xsl:number format="000000001" level="any" />
  </xsl:variable>   
  <xsl:variable name="href" select="concat('file:///', encode-for-uri( concat( $base-dir, $doc-no)),'.xml')" />
  <xsl:result-document href="{$href}" indent="yes" encoding="utf-8" omit-xml-declaration="yes">
  <xsl:apply-templates select="/*" mode="mini-doc">
    <xsl:with-param name="Mobile" tunnel="yes" select="." />
  </xsl:apply-templates>
  </xsl:result-document>
</xsl:template>

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

<xsl:template match="Mobile" mode="mini-doc">
  <xsl:param name="Mobile" tunnel="yes" />
  <xsl:if test=". is $Mobile">
    <xsl:next-match />
  </xsl:if>
</xsl:template>

</xsl:stylesheet>


主输出文档是nil,但是如果这不是您想要的,那么只需将nil的序列构造函数替换为
xsl:copy of
。将基本目录作为参数传递到此样式表,参数名为
base dir

,您还可以解释一下为什么要以这种方式拆分文件吗?嗨,Tomalak,这个XML文件的原始设计包含大量手机号码数据。这使得我的软件很难在数据上运行。我需要分割成更小的处理记录。考虑改变你的软件来使用SAX解析器。它们可以比DOM解析器更好地处理大型XML文件。确切地说,根据您所做的工作,这可能是一种比拆分文件更明智的方法。@Tomalak,将一个大XML文件拆分为多个小文件通常比编写SAX应用程序方便得多。SAX很难,我们不应该向人们推荐它,除非我们非常确定他们有足够的编程经验——我们看到这里有很多人在使用SAX时弄得一团糟。无论如何,他不是在使用DOM解析器,而是在使用XSLT。@MichaelKay他之所以使用XSLT,是因为他的主要应用程序(我猜是在使用DOM解析器)与XML打交道,他在寻找一种使其更易于管理的方法。在这种情况下,建议至少看一看SAX并不太遥远。嗨,肖恩,非常感谢,这是工作!!顺便问一下,我们想知道是否可以在2个子节点的基础上拆分它?或者如果我想排除其中的一些子节点内容?非常感谢你的帮助!当然要排除某些子文档内容,请使用模式
mini-doc
添加模板。如果“基于2个子元素拆分”,您的意思是在每个mini doc中放置两个移动元素,使用for each group指令将它们配对,并将两个元素的序列作为隧道参数传递。相应地更改if测试。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DATA>
    <Account Number='1536764-9'>
        <T1>testing1</T1>
        <T2>testing2</T2>
        <T3>testing3</T3>
        <T4>testing4</T4>
        <Mobile Number='32345'>
            <InvoiceNo>40800844</InvoiceNo>
            <SO_RC>
                <Code>7679</Code>
                <Description>GPS - Fleet Management Service</Description>
                <Amt>268.00</Amt>
                <PeriodFromDate>01/08/2015</PeriodFromDate>
                <PeriodToDate>31/08/2015</PeriodToDate>
            </SO_RC>
            <TotalSubscriber>268.00</TotalSubscriber>
        </Mobile>
    </Account>
    <Total_Records>212</Total_Records>
    <Total_Outstanding_Balance>0.00</Total_Outstanding_Balance>
    <Total_Current_Bill_Amt>0.00</Total_Current_Bill_Amt>
</DATA>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  version="2.0"
  exclude-result-prefixes="xs xsi">

<xsl:output indent="yes" encoding="utf-8" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />

<xsl:param name="base-dir" select="'C:\What-ever-directory\'" /> 

<xsl:template match="/">
  <xsl:apply-templates select="DATA/Account/Mobile" />
  <empty xsi:nil="true" />
</xsl:template>

<xsl:template match="Mobile">
  <xsl:variable name="doc-no" as="xs:string">
    <xsl:number format="000000001" level="any" />
  </xsl:variable>   
  <xsl:variable name="href" select="concat('file:///', encode-for-uri( concat( $base-dir, $doc-no)),'.xml')" />
  <xsl:result-document href="{$href}" indent="yes" encoding="utf-8" omit-xml-declaration="yes">
  <xsl:apply-templates select="/*" mode="mini-doc">
    <xsl:with-param name="Mobile" tunnel="yes" select="." />
  </xsl:apply-templates>
  </xsl:result-document>
</xsl:template>

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

<xsl:template match="Mobile" mode="mini-doc">
  <xsl:param name="Mobile" tunnel="yes" />
  <xsl:if test=". is $Mobile">
    <xsl:next-match />
  </xsl:if>
</xsl:template>

</xsl:stylesheet>