XML-фильтрация в C # - PullRequest
       2

XML-фильтрация в C #

1 голос
/ 10 января 2012

У меня есть исходный XML-файл.и я предоставляю пользовательский интерфейс для выбора элементов, которые они хотят включить в результирующий XML.Как работает пользовательский интерфейс, загружая файл XSD и представляя элементы в дереве флажков .Затем пользователи могут проверить нужные им элементы.

Пользовательский интерфейс работает нормально, но мне нужны некоторые советы / рекомендации по логике внутреннего интерфейса: в основном я хочу «применить фильтр» к исходному XML, но

  1. как сохранить выбор пользователя (в значениях, разделенных разделителем или ??) и
  2. как применить этот «фильтр» (возможно, с XSLT)?

РЕДАКТИРОВАТЬ: Структура src xml выглядит следующим образом:

<IDs>
  <id1></id1>
  <id2></id2>
  ...
</IDs>
<Traveler>
  <name></name>
  <email></email>
  ...
<Traveler>
<Segments>
  <Segment i:type="Air">
    <carrier></carrier>
    ...
  </Segment>
  <Segment i:type="Hotel">
    <supplier></supplier>
    ...
  </Segment>
</Segments>
<Notes>
...
</Notes>

EDIT2: Все эти элементы можно включить или отключить, чтобы включить врезультирующий xml.

Ответы [ 3 ]

2 голосов
/ 10 января 2012

Если вы действительно хотите сделать это с помощью XSLT, попробуйте этот подход. Он копирует все элементы и атрибуты, которые не соответствуют ни одному выражению XPath, добавленному во второй шаблон. Вам придется динамически сгенерировать XSLT и скомпилировать его, чтобы он не был особенно быстрым:

<?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="XPath for all non-selected elements"></xsl:template>
</xsl:stylesheet>
1 голос
/ 10 января 2012

Обработка во многом зависит от структуры XML, которую вы не показывали.

Это может быть так просто, как этот :

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

 <xsl:param name="pWanted" select="'|A|C|'"/>

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

 <xsl:template match="*/*">
   <xsl:if test="contains($pWanted, concat('|',name(), '|'))">
    <xsl:call-template name="identity"/>
   </xsl:if>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к следующему документу XML :

<t>
    <A>1</A>
    <B>2</B>
    <C>3</C>
</t>

желаемый, правильный результат получается (в выводе остаются только указанные пользователем элементы A и C):

<t>
   <A>1</A>
   <C>3</C>
</t>
1 голос
/ 10 января 2012

Когда мы создали удобный для пользователя инструмент для работы с нашими файлами конфигурации сервера (которые не совсем удобны для пользователя в формате XML), мы решили сохранить выбор пользователя (отличия от конфигурации по умолчанию) непосредственно в виде XSL-преобразования..

В вашем случае это также должно работать, но это зависит от точной структуры вашего XML.Если ваш исходный XML-код похож на

<data>
  <item id="1">...</item>
  <item id="2">...</item>
  ...
</data>

Вы можете сохранить выбор как, например:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/data">
    <data>
        <xsl:apply-templates select="item" />
    </data>
    </xsl:template>

    <xsl:template match="item[@id='1']">
    <xsl:copy-of select="."/>
    </xsl:template>
    <xsl:template match="item[@id='3']">
    <xsl:copy-of select="."/>
    </xsl:template>
    <xsl:template match="item[@id='4']">
    <xsl:copy-of select="."/>
    </xsl:template>

    <xsl:template match="node()" />
</xsl:stylesheet>

Это достаточно просто, ваш инструмент должен иметь возможность загрузить его обратно и позволить пользователюизменить его выбор.

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