XSL之后失去XML结构

时间:2016-03-04 14:54:47

标签: xml xslt soap xslt-1.0

我是所有这一切的新手并尝试了各种途径,但我无法提取我需要的数据。我正在使用的XML文件由一块硬件自动生成,其大小通常约为35Kb。在XML文件中有一个XSD文件的引用,我没有。

我需要提取的信息如下:

   -n:D 
   -n:S
   -filter :
      -node CUS with n:did='1', 
      -child node CU with n:u='1'
      -grandchild node D with n:c='c' 
      -sort the grandchild by n:f 
      -extract the grand-grandchild n:Q
      -add all n:Q value for similar n:f from different nodes

如下所示,这是一个非常复杂的结构。每次我在节点上测试一个条件时,我都会在输出中松开整个XML结构。

以下是XML文件的一部分:

<?xml version="1.0" encoding="UTF-8"?>
   <soapenv:E xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:B>
         <n:IR xmlns:n="http://abc.xxx/bb.xsd" n:result="0">
            <n:D>2016/02/11 09:11:15</n:D>
            <n:S>1</n:S>
            <C n:t="3">
                 <D n:c="C" n:f="1" n:r="0" n:did="1">
                    <n:Q>10</n:Q>
                    <n:St>2</n:St>
                </D>
            ...
                <D n:c="C" n:f="5" n:r="0" n:did="1">
                    <n:Q>12</n:Q>
                    <n:St>2</n:St>
                </D>
                <D n:c="U" n:f="20" n:r="0" n:did="1">
                    <n:Q>1</n:Q>
                    <n:St>2</n:St>
                </D>
            ...
                <D n:c="U" n:f="5" n:r="0" n:did="1">
                    <n:Q>5</n:Q>
                    <n:St>2</n:St>
                </D>
                <D n:c="C" n:f="1" n:r="0" n:did="2">
                     <n:Q>5</n:Q>
                    <n:St>2</n:St>
                </D>
             ...
                <D n:c="C" n:f="100" n:r="0" n:did="2">
                    <n:Q>5</n:Q>
                    <n:St>2</n:St>
                </D>
            </C>
            <C n:t="4">
                <D n:c="C" n:f="1" n:r="0" n:did="1">
                    <n:Q>1</n:Q>
                    <n:St>2</n:St>
                </D>
            ...
                <D n:c="C" n:f="5" n:r="0" n:did="1">
                    <n:Q>2</n:Q>
                    <n:St>2</n:St>
                </D>
                <D n:c="U" n:f="20" n:r="0" n:did="1">
                    <n:Q>1</n:Q>
                    <n:St>2</n:St>
                </D>
            ...
                <D n:c="U" n:f="5" n:r="0" n:did="1">
                    <n:Q>3</n:Q>
                    <n:St>2</n:St>
                </D>
                <D n:c="C" n:f="1" n:r="0" n:did="2">
                    <n:Q>2</n:Q>
                    <n:St>2</n:St>
                </D>
            ...
                <D n:c="C" n:f="100" n:r="0" n:did="2">
                    <n:Q>3</n:Q>
                    <n:St>2</n:St>
                </D>
            </C>
            <CUS n:did="1">
                <CU n:u="1a" n:st="22" n:nf="90" n:ne="10" n:max="110"/>
                <CU n:u="1" n:st="0" n:nf="100" n:ne="9" n:mx="105">
                    <D n:c="C" n:f="1" n:r="0" n:did="1">
                        <n:Q>3</n:Q>
                        <n:St>2</n:St>
                     </D>
                ...
                    <D n:c="U" n:f="5" n:r="0" n:did="1">
                        <n:Q>12</n:Q>
                        <n:St>2</n:St>
                    </D>
                </CU>
                <CU n:u="2" n:st="0" n:nf="100" n:ne="9" n:mx="105"/>
            ...
                <CU n:u="10" n:st="0" n:nf="100" n:ne="9" n:mx="105"/>
            </CUS>
            <CUS n:did="1">
                <CU n:u="1" n:st="0" n:nf="100" n:ne="9" n:mx="105">
                    <D n:c="C" n:f="1" n:r="0" n:did="2">
                        <n:Q>3</n:Q>
                        <n:St>2</n:St>
                    </D>
                ...
                    <D n:c="C" n:f="5" n:r="0" n:did="2">
                        <n:Q>12</n:Q>
                        <n:St>2</n:St>
                    </D>
                </CU>
                <CU n:u="2" n:st="0" n:nf="100" n:ne="9" n:mx="105"/>
            ...
                <CU n:u="10" n:st="0" n:nf="100" n:ne="9" n:mx="105">
                    <D n:c="C" n:f="1" n:r="0" n:did="2">
                        <n:Q>4</n:Q>
                        <n:St>2</n:St>
                    </D>
                ...
                    <D n:c="C" n:f="5" n:r="0" n:did="2">
                        <n:Q>10</n:Q>
                        <n:St>2</n:St>
                    </D>
                </CU>
            </CUS>
        </n:IR>
    </soapenv:B>
</soapenv:E>

以下是我试图隔离我需要的XML文件部分的XSL文件的开头:

<?xml version = "1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version = "1.0"
                         xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope"
                         xmlns:n="http://abc.xxx/bb.xsd">

<xsl:output method="xml" indent="yes"/>
    <xsl:template match="*">
        <xsl:apply-templates select="*"/>
    </xsl:template>

    <xsl:template match="*">
        <xsl:copy>
            <xsl:for-each select="//CU">
                <xsl:copy/>
            </xsl:for-each>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="C"/>
</xsl:stylesheet>

我得到的结果是:

<?xml version="1.0"?>
<soapenv:E xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:B>
<n:IR xmlns:n="http://abc.xxx/bb.xsd">
<n:D>2016/02/11 09:11:15</n:D>
<n:S>1</n:S>
<CUS>
<CU>
<D>
<n:Q>0</n:Q>
<n:St>0</n:St>
</D>
</CU>
<CU>
<D>
<n:Q>0</n:Q>
<n:St>0</n:St>
</D>
</CU>
....
</CUS>
</n:IR>
</soapenv:B>
</soapenv:E>

通过这个结果,我不再能够过滤节点来提取我需要添加数据的节点 有什么建议?

对不起错字:日期应该是n:D以上。 预期结果应与此类似:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:E xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:B>
  <n:IR xmlns:n="http://abc.xxx/bb.xsd" n:result="0">
   <n:Date>2016/02/11 09:11:15</n:Date>
   <n:S>1</n:S>
   <CUS n:did="1">
    <CU n:u="1" n:st="0" n:nf="100" n:ne="9" n:mx="105">
     <D n:c="C" n:f="5" n:r="0" n:did="1">
      <n:Q>3</n:Q>
      <n:St>2</n:St>
     </D>
     <D n:c="C" n:f="10" n:r="0" n:did="1">
      <n:Q>2</n:Q>
      <n:St>2</n:St>
     </D>
     <D n:c="C" n:f="20" n:r="0" n:did="1">
      <n:Q>5</n:Q>
      <n:St>2</n:St>
     </D>
    </CU>
    <CU n:u="2" n:st="0" n:nf="100" n:ne="9" n:mx="105">
     <D n:c="C" n:f="5" n:r="0" n:did="1">
      <n:Q>1</n:Q>
      <n:St>2</n:St>
     </D>
     <D n:c="C" n:f="20" n:r="0" n:did="1">
      <n:Q>1</n:Q>
      <n:St>2</n:St>
    </D>
    <D n:c="C" n:f="50" n:r="0" n:did="1">
     <n:Q>3</n:Q>
     <n:St>2</n:St>
    </D>
   </CU>
  </CUS>
 </n:IR>
</soapenv:B>
</soapenv:E>

但最终结果是像这样的文本格式

2016/02/11 09:11:15,1,4,2,6,3

其中4是和n:Q来自CU n:u ='1'和n:U ='2'对于n:c ='C',n:f ='5'和n:did =' 1'等等其他值。

1 个答案:

答案 0 :(得分:0)

I am afraid I can only give you a starting point. The following stylesheet:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:n="http://abc.xxx/bb.xsd">
<xsl:output method="text" encoding="UTF-8" />
<xsl:strip-space elements="*"/>

<xsl:template match="n:IR">
    <xsl:value-of select="n:D" />
    <xsl:text>,</xsl:text>
    <xsl:value-of select="n:S" />
    <xsl:text>,</xsl:text>
    <xsl:value-of select="sum(CUS[@n:did='1']/CU[@n:u='1']/D[@n:c='C']/n:Q)" />
    <!-- ... -->
</xsl:template>

</xsl:stylesheet>

applied to your example input, will return:

2016/02/11 09:11:15,1,18

I suggest you run with this and post additional specific question as you encounter specific problems.

P.S. I don't see why you would need an interim XMl result, if your final result needs to be text.