Как бы я динамически добавить новый узел XML на основе значений других узлов?

Предыстория: у
меня есть старая веб-CMS, которая хранила контент в XML-файлах, по одному XML-файлу на страницу. Я нахожусь в процессе импорта контента из этой CMS в новую, и я знаю, что мне нужно будет поменять существующий XML, чтобы процесс импорта работал правильно.

Существующий XML:

<page>
    <audience1>true</audience>
    <audience2>false</audience>
    <audience3>true</audience>
    <audience4>false</audience>
    <audience5>true</audience>
</page>

Желаемый XML:

<page>
    <audience1>true</audience>
    <audience2>false</audience>
    <audience3>true</audience>
    <audience4>false</audience>
    <audience5>true</audience>
    <audiences>1,3,5</audiences>
</page>

Вопрос:
Требуемый XML добавляет узел с разделенным запятыми списком других узлов, имеющих «истинное» значение. Мне нужно получить желаемый XML для нескольких файлов, так как лучше всего это сделать? Некоторые из моих идей:

  • Используйте текстовый редактор с регулярным выражением найти / заменить. Но какое выражение? Я даже не знаю, с чего начать.
  • Используйте язык программирования, например ASP.NET, для анализа файлов и добавления нужного узла. Опять же, я не уверен, с чего начать, так как мои навыки .NET только средние.

Предложения?

11.12.2008 01:13:46
XSLT - это общее решение, манипуляции с XpathDocument - это конкретное решение, регулярные выражения вообще не являются решением.
annakata 12.12.2008 13:14:49
2 ОТВЕТА

Я бы, вероятно, использовал класс XmlDocument в .net, но это только я, потому что я никогда не любил регулярные выражения.

Затем вы можете использовать выражения XPath для извлечения дочерних узлов каждого узла страницы, их оценки и добавления нового узла в конце дочерних узлов страницы, сохраняя XmlDocument, когда вы закончите.

Xsl тоже вариант, но начальная кривая обучения немного болезненна.

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

1
11.12.2008 01:27:39

Я бы, вероятно, использовал таблицу стилей XSLT для решения этой проблемы. Я построил следующую таблицу стилей, чтобы она была немного общей и соответствовала именно тому, что вы просили, но ее можно легко изменить, чтобы получить точный вывод, который вы указали, если вам действительно нужен именно этот вывод.

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <xsl:apply-templates select="/*"/>
</xsl:template>

  <xsl:template match="/*">
    <xsl:copy>
      <xsl:copy-of select="*"/>

        <xsl:element name="nodes">
          <xsl:apply-templates select="*[normalize-space(.) = 'true']"/>
        </xsl:element>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="/*/*">
    <xsl:value-of select="concat(',', local-name())"/>
  </xsl:template>

  <xsl:template match="/*/*[1]">
    <xsl:value-of select="local-name()"/>
  </xsl:template>

</xsl:stylesheet> 

Этот вывод XSLT будет:

<page>
  <audience1>
    true
  </audience1>
  <audience2>
    false
  </audience2>
  <audience3>
    true
  </audience3>
  <audience4>
    false
  </audience4>
  <audience5>
    true
  </audience5>
  <nodes>audience1,audience3,audience5</nodes>
</page>

XSLT отлично подойдет для этого, потому что вы можете использовать практически любой язык программирования или использовать Visual Studio для применения шаблона. Есть также много бесплатных инструментов , которые вы можете использовать для применения преобразований.

1
12.12.2008 13:38:15