удалить дубликаты узлов из файла XML (XSLT-преобразование) - PullRequest
0 голосов
/ 23 ноября 2018

Я был бы признателен, если бы кто-нибудь помог мне создать xslt для удаления дубликатов узлов из XML на основе значения дублированного атрибута.В приведенном ниже примере атрибутами являются PublisherName и Data

Input

        <RuleCollection>
<FilePublisherRule Id="1">
    <Conditions>
        <FilePublisherCondition PublisherName="O=Vendor1">
            <BinaryVersionRange LowSection="*" HighSection="*" />
        </FilePublisherCondition>
    </Conditions>
</FilePublisherRule>
<FilePublisherRule Id="2">
    <Conditions>
        <FilePublisherCondition PublisherName="O=Vendor2">
            <BinaryVersionRange LowSection="*" HighSection="*" />
        </FilePublisherCondition>
    </Conditions>
</FilePublisherRule>
<FilePublisherRule Id="3">
    <Conditions>
        <FilePublisherCondition PublisherName="O=Vendor1">
            <BinaryVersionRange LowSection="*" HighSection="*" />
        </FilePublisherCondition>
    </Conditions>
</FilePublisherRule>    
<FileHashRule Id="10">
    <Conditions>
        <FileHashCondition>
            <FileHash Type="SHA256" Data="0xF11BD15D6A565071AED8D3581012C5B5EE0AB46795CEF4ECD712F7572A3DBE36" SourceFileName="_IU14D2N.TMP" SourceFileLength="0" />
            <FileHash Type="SHA256" Data="0xF11BD15D6A565071AED8D3581012C5B5EE0AB46795CEF4ECD712F7572A3DBE36" SourceFileName="UNINS000.EXE" SourceFileLength="0" />
            <FileHash Type="SHA256" Data="0x5831F348B9B2744F56631CFB2FCAB676BD8B9D3EE407A2DE2C66BC3C395A9E73" SourceFileName="CO.EXE" SourceFileLength="0" />
            <FileHash Type="SHA256" Data="0x4BA8285055A9CF8EE146F738DC8526CCD1E509B03984FE1914A6826C7CD530EE" SourceFileName="SETUPCO.EXE" SourceFileLength="0" />
            <FileHash Type="SHA256" Data="0x4BA8285055A9CF8EE146F738DC8526CCD1E509B03984FE1914A6826C7CD530EE" SourceFileName="SETUPDAR.EXE" SourceFileLength="0" />
        </FileHashCondition>
    </Conditions>
</FileHashRule>
<RuleCollection/>

Мне нужно

<RuleCollection>
<FilePublisherRule Id="1">
    <Conditions>
        <FilePublisherCondition PublisherName="O=Vendor1">
            <BinaryVersionRange LowSection="*" HighSection="*" />
        </FilePublisherCondition>
    </Conditions>
</FilePublisherRule>
<FilePublisherRule Id="2">
    <Conditions>
        <FilePublisherCondition PublisherName="O=Vendor2">
            <BinaryVersionRange LowSection="*" HighSection="*" />
        </FilePublisherCondition>
    </Conditions>
</FilePublisherRule>
<FileHashRule Id="10">
    <Conditions>
        <FileHashCondition>
            <FileHash Type="SHA256" Data="0xF11BD15D6A565071AED8D3581012C5B5EE0AB46795CEF4ECD712F7572A3DBE36" SourceFileName="UNINS000.EXE" SourceFileLength="0" />
            <FileHash Type="SHA256" Data="0x5831F348B9B2744F56631CFB2FCAB676BD8B9D3EE407A2DE2C66BC3C395A9E73" SourceFileName="CO.EXE" SourceFileLength="0" />
            <FileHash Type="SHA256" Data="0x4BA8285055A9CF8EE146F738DC8526CCD1E509B03984FE1914A6826C7CD530EE" SourceFileName="SETUPCO.EXE" SourceFileLength="0" />
        </FileHashCondition>
    </Conditions>
</FileHashRule>
<RuleCollection/>

Я проверил некоторые уже существующие случаи, и кажется, что мне нужно использоватьНесколько шаблонов в xslt и используют группировку Munechian, но у меня нет опыта.

Я обработал удаление дублированных узлов FileHash, используя этот xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 version="1.0">
 <xsl:output omit-xml-declaration="no" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kPropertyByName" match="FileHash" use="@Data"/>

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

 <xsl:template
 match="FileHash[
         not(
           generate-id() =
           generate-id(key('kPropertyByName', @Data)[1])
         )
       ]"/>

 </xsl:stylesheet>

Кроме того, у меня выходной файл больше исходного, почему?Мне нужно поменьшеИ я предполагаю, что следующим шагом будет добавление второго шаблона для обработки удаления узла FilePublisherRule на основе значения опубликованного имени

Я добавил второй шаблон

         <xsl:template
       match="FileHash[
            not(
             generate-id() =
             generate-id(key('kPropertyByName', @Data)[1])
              )
           ]"/>

              <xsl:template
       match="FilePublisherCondition[
             not(
               generate-id() =
              generate-id(key('kProperty1ByName', @PublisherName)[1])
             )

дублирует узлы FilePublisherCondition удалено, но родительские узлы остались

        <FilePublisherRule Id="0355cba7-7d4a-4a74-9579-8d2192fa0514" Name="Signed by O=ADOBE SYSTEMS INCORPORATED, L=SAN JOSE, S=CALIFORNIA, C=US" Description="" UserOrGroupSid="S-1-1-0" Action="Allow">
    <Conditions>
    <FilePublisherCondition PublisherName="O=ADOBE SYSTEMS INCORPORATED, L=SAN JOSE, S=CALIFORNIA, C=US" ProductName="*" BinaryName="*">
    <BinaryVersionRange LowSection="*" HighSection="*"></BinaryVersionRange>
    </FilePublisherCondition>
    </Conditions>
    </FilePublisherRule>
    <FilePublisherRule Id="0355cba7-7d4a-4a74-9579-8d2192fa0514" Name="Signed by O=ADOBE SYSTEMS INCORPORATED, L=SAN JOSE, S=CALIFORNIA, C=US" Description="" UserOrGroupSid="S-1-1-0" Action="Allow">
    <Conditions></Conditions>
    </FilePublisherRule>
    <FilePublisherRule Id="0355cba7-7d4a-4a74-9579-8d2192fa0514" Name="Signed by O=ADOBE SYSTEMS INCORPORATED, L=SAN JOSE, S=CALIFORNIA, C=US" Description="" UserOrGroupSid="S-1-1-0" Action="Allow">
    <Conditions></Conditions>
    </FilePublisherRule>
    <FilePublisherRule Id="e9a23377-81af-41dd-b65d-d8f45c7eac7f" Name="myAgent (O=FLEXERA SOFTWARE LLC, L=SCHAUMBURG, S=ILLINOIS, C=US)" Description="myAgent (6.2.1.172)" UserOrGroupSid="S-1-1-0" Action="Allow">
    <Conditions>
    <FilePublisherCondition PublisherName="O=FLEXERA SOFTWARE LLC, L=SCHAUMBURG, S=ILLINOIS, C=US" ProductName="*" BinaryName="*">
    <BinaryVersionRange LowSection="*" HighSection="*"></BinaryVersionRange>
    </FilePublisherCondition>
    </Conditions>
    </FilePublisherRule>
    <FilePublisherRule Id="e9a23377-81af-41dd-b65d-d8f45c7eac7f" Name="myAgent (O=FLEXERA SOFTWARE LLC, L=SCHAUMBURG, S=ILLINOIS, C=US)" Description="myAgent (6.2.1.172)" UserOrGroupSid="S-1-1-0" Action="Allow">
    <Conditions></Conditions>
    </FilePublisherRule>
    <FileHashRule Id="c4232cc1-563b-4fa7-84da-19331af01de4" Name="communication clients" Description="" UserOrGroupSid="S-1-1-0" Action="Allow">
    <Conditions>    

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Для устранения дубликатов FilePublisherRule, основанных на атрибуте внуков, вы можете просто добавить ключ и другой пустой шаблон, используя этот ключ:

  <xsl:key name="publisherName" match="FilePublisherRule" use="Conditions/FilePublisherCondition/@PublisherName"/>

  <xsl:template match="FilePublisherRule[not(generate-id() = generate-id(key('publisherName', Conditions/FilePublisherCondition/@PublisherName)[1]))]"/>

https://xsltfiddle.liberty -развитие.сеть / bFDb2Dj

0 голосов
/ 23 ноября 2018

Ваше решение относительно удаления повторяющихся FileHash элементов является правильным, хотя его можно немного упростить (см. Ниже в моем коде).

Чтобы исключить FilePublisherRule элементов, содержащих повторяющиеся атрибуты PublisherName,мы должны сделать аналогичным образом:

  1. Создать key (я назвал его kPubl), соответствующий FilePublisherCondition, используя @PublisherName.
  2. Написать соответствующий шаблонFilePublisherRule и внутри него:
    • Сохранить Conditions/FilePublisherCondition под переменной (я назвал ее fpCond)
    • Проверить равенство generate-id для $fpCond и прочитать первый ключ изkPubl, для $fpCond/@PublisherName.
    • Если они равны, скопируйте текущий элемент (я использовал copy и apply-templates, как в шаблоне идентификации ).
    • В противном случае ничего не делать (пропустить этот элемент).

Таким образом, весь сценарий XSLT может быть следующим:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="kData" match="FileHash" use="@Data"/>
  <xsl:key name="kPubl" match="FilePublisherCondition" use="@PublisherName"/>

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

  <xsl:template match="FileHash[generate-id() !=
    generate-id(key('kData', @Data)[1])]"/>

  <xsl:template match="FilePublisherRule">
    <xsl:variable name="fpCond" select="Conditions/FilePublisherCondition"/>
    <xsl:if test="generate-id($fpCond) = generate-id(key('kPubl', $fpCond/@PublisherName)[1])">
      <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Для работающегопример см. http://xsltransform.net/6qaFCEf

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...