Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > XML, XSL > скопировать часть нод второго порядка другой xml


Автор: leniviy 16.11.2012, 18:18
структура xml файла такая:
Код

<root>
<CallEventRecord>
    <ggsnPDPRecord>
        <servedMSISDN>txt</servedMSISDN>
        ...
    </ggsnPDPRecord>
</CallEventRecord>

<CallEventRecord>
    <sgsnPDPRecord>
        <servedMSISDN>txt</servedMSISDN>
        ...
    </sgsnPDPRecord>
</CallEventRecord>

</root>


Мне нужно выбрать ggsnPDPRecord, но не sgsnPDPRecord, у которых servedMSISDN = '91 14 97 85 03 91 F0'
Я написал некий xslt, но чувствую, что не правильно:
Код

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

  <xsl:template match="node()[(. != /) and (.. = /) and (name() != 'CallEventRecord' or not(ggsnPDPRecord))]"/>
  <xsl:template match="node()[(. != /) and (.. = /) and not(ggsnPDPRecord/servedMSISDN/text()[. = '91 14 97 85 03 91 F0'])]"/>

</xsl:stylesheet>

Это переработанный пример http://stackoverflow.com/questions/3816764/trying-to-filter-xml-using-xpath .
(. != /) and (.. = /) - чтобы матчилась нода только второго порядка.
Мне выносит мозг то, что нужное мне условие надо отрицать. Если бы можно было забить положительное условие в 
<xsl:apply-templates select="..."/>, было бы удобнее, но я не знаю, как.

small.xml:
Код

<root>
<CallEventRecord>
    <sgsnPDPRecord>
        <recordType><ggsnPDPRecord/></recordType>
        <servedIMSI>22 08 41 11 85 08 38 F0</servedIMSI>
        <ggsnAddress>
            <iPBinaryAddress>
                <iPBinV4Address>8A BC 02 01</iPBinV4Address>
            </iPBinaryAddress>
        </ggsnAddress>
        <chargingID>1471674127</chargingID>
        <sgsnAddress>
                <iPBinaryAddress>
                    <iPBinV4Address>8A BC 03 03</iPBinV4Address>
                </iPBinaryAddress>
            
        </sgsnAddress>
        <accessPointNameNI>event.swisscom.ch</accessPointNameNI>
        <pdpType>01 21</pdpType>
        <servedPDPAddress>
            <iPAddress>
                <iPBinaryAddress>
                    <iPBinV4Address>0A 71 04 A7</iPBinV4Address>
                </iPBinaryAddress>
            </iPAddress>
        </servedPDPAddress>
        <dynamicAddressFlag><true/></dynamicAddressFlag>
        <listOfTrafficVolumes>
            <ChangeOfCharCondition>
                <qosNegotiated>
                    <umtsQosInformation>02 13 62 1F 73 96 40 68 74 62 10 40</umtsQosInformation>
                </qosNegotiated>
                <dataVolumeGPRSUplink>0</dataVolumeGPRSUplink>
                <dataVolumeGPRSDownlink>0</dataVolumeGPRSDownlink>
                <changeCondition><recordClosure/></changeCondition>
                <changeTime>12 08 14 23 46 57 2B 02 00</changeTime>
            </ChangeOfCharCondition>
        </listOfTrafficVolumes>
        <recordOpeningTime>12 08 14 23 46 57 2B 02 00</recordOpeningTime>
        <duration>0</duration>
        <causeForRecClosing><normalRelease/></causeForRecClosing>
        <recordExtensions>
            <ManagementExtension>
                <identifier>1.2.840.113533.4.10.1.2.1</identifier>
                <significance><true/></significance>
                <information>
                    16 10 2A 73 74 2D 74 2D 65 76 65 6E 74 2E 73 77 
                    69 73
                </information>
            </ManagementExtension>
            <ManagementExtension>
                <identifier>1.2.840.113533.4.10.1.7.1</identifier>
                <significance><true/></significance>
                <information>04 08 53 89 18 30 40 39 34 20</information>
            </ManagementExtension>
        </recordExtensions>
        <localSequenceNumber>262970429</localSequenceNumber>
        <apnSelectionMode><mSorNetworkProvidedSubscriptionVerified/></apnSelectionMode>
        <servedMSISDN>91 14 97 85 03 91 F0</servedMSISDN>
        <chargingCharacteristics>04 00</chargingCharacteristics>
    </sgsnPDPRecord>
</CallEventRecord>
<CallEventRecord>
    <ggsnPDPRecord>
        <recordType><ggsnPDPRecord/></recordType>
        <servedIMSI>22 08 41 11 85 08 38 F0</servedIMSI>
        <ggsnAddress>
            <iPBinaryAddress>
                <iPBinV4Address>8A BC 02 01</iPBinV4Address>
            </iPBinaryAddress>
        </ggsnAddress>
        <chargingID>1471674327</chargingID>
        <sgsnAddress>
                <iPBinaryAddress>
                    <iPBinV4Address>8A BC 03 03</iPBinV4Address>
                </iPBinaryAddress>
            
        </sgsnAddress>
        <accessPointNameNI>event.swisscom.ch</accessPointNameNI>
        <pdpType>01 21</pdpType>
        <servedPDPAddress>
            <iPAddress>
                <iPBinaryAddress>
                    <iPBinV4Address>0A 71 00 8A</iPBinV4Address>
                </iPBinaryAddress>
            </iPAddress>
        </servedPDPAddress>
        <dynamicAddressFlag><true/></dynamicAddressFlag>
        <listOfTrafficVolumes>
            <ChangeOfCharCondition>
                <qosNegotiated>
                    <umtsQosInformation>02 13 62 1F 73 96 40 68 74 62 10 40</umtsQosInformation>
                </qosNegotiated>
                <dataVolumeGPRSUplink>0</dataVolumeGPRSUplink>
                <dataVolumeGPRSDownlink>0</dataVolumeGPRSDownlink>
                <changeCondition><recordClosure/></changeCondition>
                <changeTime>12 08 14 23 48 28 2B 02 00</changeTime>
            </ChangeOfCharCondition>
        </listOfTrafficVolumes>
        <recordOpeningTime>12 08 14 23 48 28 2B 02 00</recordOpeningTime>
        <duration>0</duration>
        <causeForRecClosing><normalRelease/></causeForRecClosing>
        <recordExtensions>
            <ManagementExtension>
                <identifier>1.2.840.113533.4.10.1.2.1</identifier>
                <significance><true/></significance>
                <information>
                    16 10 2A 73 74 2D 74 2D 65 76 65 6E 74 2E 73 77 
                    69 73
                </information>
            </ManagementExtension>
            <ManagementExtension>
                <identifier>1.2.840.113533.4.10.1.7.1</identifier>
                <significance><true/></significance>
                <information>04 08 53 89 18 30 40 39 34 20</information>
            </ManagementExtension>
        </recordExtensions>
        <localSequenceNumber>262971067</localSequenceNumber>
        <apnSelectionMode><mSorNetworkProvidedSubscriptionVerified/></apnSelectionMode>
        <servedMSISDN>91 14 97 85 03 91 F0</servedMSISDN>
        <chargingCharacteristics>04 00</chargingCharacteristics>
    </ggsnPDPRecord>
</CallEventRecord>
<CallEventRecord>
    <ggsnPDPRecord>
        <recordType><ggsnPDPRecord/></recordType>
        <servedIMSI>22 08 31 13 27 18 10 F0</servedIMSI>
        <ggsnAddress>
            <iPBinaryAddress>
                <iPBinV4Address>8A BC 02 01</iPBinV4Address>
            </iPBinaryAddress>
        </ggsnAddress>
        <chargingID>1471649563</chargingID>
        <sgsnAddress>
                <iPBinaryAddress>
                    <iPBinV4Address>97 02 E0 41</iPBinV4Address>
                </iPBinaryAddress>
            
        </sgsnAddress>
        <accessPointNameNI>event.swisscom.ch</accessPointNameNI>
        <pdpType>01 21</pdpType>
        <servedPDPAddress>
            <iPAddress>
                <iPBinaryAddress>
                    <iPBinV4Address>0A 71 CE 28</iPBinV4Address>
                </iPBinaryAddress>
            </iPAddress>
        </servedPDPAddress>
        <dynamicAddressFlag><true/></dynamicAddressFlag>
        <listOfTrafficVolumes>
            <ChangeOfCharCondition>
                <qosNegotiated>
                    <umtsQosInformation>02 1B 62 1F 73 96 40 68 74 63 10 40</umtsQosInformation>
                </qosNegotiated>
                <dataVolumeGPRSUplink>0</dataVolumeGPRSUplink>
                <dataVolumeGPRSDownlink>0</dataVolumeGPRSDownlink>
                <changeCondition><recordClosure/></changeCondition>
                <changeTime>12 08 14 23 48 32 2B 02 00</changeTime>
            </ChangeOfCharCondition>
        </listOfTrafficVolumes>
        <recordOpeningTime>12 08 14 21 48 32 2B 02 00</recordOpeningTime>
        <duration>7200</duration>
        <causeForRecClosing><timeLimit/></causeForRecClosing>
        <recordSequenceNumber>1</recordSequenceNumber>
        <recordExtensions>
            <ManagementExtension>
                <identifier>1.2.840.113533.4.10.1.2.1</identifier>
                <significance><true/></significance>
                <information>
                    16 10 2A 73 74 2D 74 2D 65 76 65 6E 74 2E 73 77 
                    69 73
                </information>
            </ManagementExtension>
            <ManagementExtension>
                <identifier>1.2.840.113533.4.10.1.7.1</identifier>
                <significance><true/></significance>
                <information>04 08 53 46 23 10 50 54 12 60</information>
            </ManagementExtension>
        </recordExtensions>
        <localSequenceNumber>262971094</localSequenceNumber>
        <apnSelectionMode><mSorNetworkProvidedSubscriptionVerified/></apnSelectionMode>
        <servedMSISDN>91 14 97 23 75 58 F7</servedMSISDN>
        <chargingCharacteristics>04 00</chargingCharacteristics>
    </ggsnPDPRecord>
</CallEventRecord>
</root>


Автор: diadiavova 17.11.2012, 15:34
Цитата(leniviy @  16.11.2012,  19:18 Найти цитируемый пост)
(. != /) and (.. = /) - чтобы матчилась нода только второго порядка.

А так не пробовал? 
/node()

Автор: leniviy 17.11.2012, 15:59
Цитата(diadiavova @  17.11.2012,  15:34 Найти цитируемый пост)
А так не пробовал? 
/node() 

Пробовал, не получилось. Это условие всегда истина, в отрыве от текущей ноды.

Автор: diadiavova 17.11.2012, 16:40
leniviy, сделал упрощенный пример, для своего случая переработай, думаю это будет несложно
Код

<?xml version="1.0" encoding="utf-8"?>
<root>
  <level1>
    <level2>
      fd;lgjk
    </level2>
  </level1>
  <level1-exclude>
    <level2>
      fd;lgjk
    </level2>
  </level1-exclude>
</root>
Из этого документа копируем все кроме элементов level1-exclude и их потомков
Код

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/*">
    <xsl:copy>
        <xsl:copy-of select="@* | node()[name() != 'level1-exclude']"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Результат
Код

<?xml version="1.0" encoding="utf-8"?>
<root>
  <level1>
    <level2>
      fd;lgjk
    </level2>
  </level1>
  
</root>


Добавлено через 14 минут и 54 секунды
И кстати вот такой вариант тоже работает
Код

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="/*/node()[name() != 'level1']"/>
</xsl:stylesheet>

То есть надо было указать условие не /node(), а /*/node()

Автор: leniviy 20.11.2012, 10:43
Есть ли разница между 
Код

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

и
Код

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

?

Автор: diadiavova 20.11.2012, 12:09
leniviy, в первом случае обработка начинается с корневого элемента, который копируется сначала сам, а потом в него вставляются дочерние узлы. Во втором обработка начинается с узла document и копируются все его потомки. Результаты могут различаться к примеру в тех случаях, когда корневому элементу исходного документа предшествуют комментарии или инструкции приложений, первый вариант их не скопирует.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)