XmlCompiledTransform дублирует пространство имен при замене значения элемента

Я пытаюсь использовать XslCompiledTransform C# класс для преобразования одного файла XML в другой. Тем не менее, пространство имен включается во второй раз в один из моих элементов (SerialNum). Что я делаю неправильно?

Вот мой код C#:

// Create a reader to read books.xml
XmlReader reader = XmlReader.Create("machine1.xml");

// Create a writer for writing the transformed file.
XmlWriter writer = XmlWriter.Create("machine2.xml");

XslCompiledTransform transform = new XslCompiledTransform();
transform.Load("transform.xsl");

// Execute the transformation.
transform.Transform(reader, writer);

Вот мой XSL:

<xsl:stylesheet version="1.0" xmlns:cm="http://schemas.datacontract.org/2004/07/CMachines" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <!-- Copy everything not subject to the exceptions below -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
<!-- Ignore the disabled element -->
<xsl:template match="cd:Disabled" />
  <!-- Reset the value of the serial num element to 0 -->
  <xsl:template match="cm:SerialNum">
    <SerialNum>0</SerialNum>
  </xsl:template>
</xsl:stylesheet>

Входные данные:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfMachine xmlns="http://schemas.datacontract.org/2004/07/CMachines" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Machine>
      <Name>DellM7600</Name>
      <ID>1</ID>
      <Type>Laptop</Type>
      <Disabled>false</Disabled>
      <SerialNum>47280420</SerialNum>
    </Machine>
    <Machine>
      <Name>DellD600</Name>
      <ID>2</ID>
      <Type>Laptop</Type>
      <Disabled>false</Disabled>
      <SerialNum>53338123</SerialNum>
    </Machine>
    </ArrayOfMachine>

Выход:

<?xml version="1.0" encoding="utf-8"?><ArrayOfMachine xmlns="http://schemas.datacontract.org/2004/07/CMachines" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Machine>
      <Name>DellM7600</Name>
      <ID>1</ID>
      <Type>Laptop</Type>
      <SerialNum xmlns="" xmlns:cm="http://schemas.datacontract.org/2004/07/CMachines">0</SerialNum>
    </Machine>
    <Machine>
      <Name>DellD600</Name>
      <ID>2</ID>
      <Type>Laptop</Type>
      <SerialNum xmlns="" xmlns:cm="http://schemas.datacontract.org/2004/07/CMachines">0</SerialNum>
    </Machine>
    </ArrayOfMachine>

Желаемый результат:

<?xml version="1.0" encoding="utf-8"?><ArrayOfMachine xmlns="http://schemas.datacontract.org/2004/07/CMachines" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Machine>
      <Name>DellM7600</Name>
      <ID>1</ID>
      <Type>Laptop</Type>
      <SerialNum>0</SerialNum>
    </Machine>
    <Machine>
      <Name>DellD600</Name>
      <ID>2</ID>
      <Type>Laptop</Type>
      <SerialNum>0</SerialNum>
    </Machine>
    </ArrayOfMachine>

1 ответ

Решение

Просто замените:

  <xsl:template match="cm:SerialNum">
    <SerialNum>0</SerialNum>
  </xsl:template>

с:

  <xsl:template match="cm:SerialNum">
    <xsl:copy>0</xsl:copy>
  </xsl:template>

Теперь у вас есть создание нового SerialNum элемент в пространстве без имен - в отличие от оригинала, который наследует пространство имен своего родителя. Вот почему вы видите xmlns="" объявление: это показывает, что элемент находится в пространстве без имен, в отличие от его родителя.

xmlns:cm="http://schemas.datacontract.org/2004/07/CMachines" просто наследуется от xsl:stylesheet предок. Вы можете устранить это, добавив exclude-result-prefixes="cm" приписать xsl:stylesheet элемент - но гораздо проще просто скопировать оригинал SerialNum элемент с исходным пространством имен и без наследования от таблицы стилей.

Другие вопросы по тегам