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

Справочная информация:
У меня есть старая веб-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 только средние.

Предложения

Ответы [ 2 ]

1 голос
/ 12 декабря 2008

Я бы, вероятно, использовал таблицу стилей 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 голос
/ 11 декабря 2008

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

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

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

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

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