Объединить ребенка в неизвестного родителя по имени - PullRequest
1 голос
/ 04 апреля 2019

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

Как это:

<?xml version="1.0" encoding="utf-8" ?>
<Blocks>
  <Block ID="OA00" Name="Generic">
    <Design ID="DA00" />
  </Block>
  <Block ID="OA01" Name="WildStar" DenyChange="true">
    <Design ID="DA00" />
    <Coordinate X="50" Y="60" />
  </Block>
  <Block ID="OA02" Name="Eraser" />
</Blocks>

В это:

<?xml version="1.0" encoding="utf-8" ?>
    <Blocks>
      <Block ID="OA00" Name="Generic">
        <Design ID="DA00" />
      </Block>
      <Block ID="OA01" Name="WildStar" DenyChange="true" X="50" Y="60" >
        <Design ID="DA00" />
      </Block>
      <Block ID="OA02" Name="Eraser" />
    </Blocks>

Однако имя Родителя не всегда "Блок", это может быть что угодно, но имя Ребенка всегда "Координата".

Это для сериализации и десериализации класса vb.net, где Coordinate - это структура внутри класса.

Этот был ближе всего к тому, что я хотел , но это не решает неизвестное имя Родителя.

Это то, что у меня есть сейчас, но я новичок в XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*" />

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

    <xsl:template match="node()">
    <xsl:variable name="name" select="name(..)" />
    <xsl:if test="*[local-name() = 'Coordinate']">
        <xsl:element name="{$name}">
        <xsl:copy-of select="@*|Coordinate/@*" />
        <xsl:apply-templates />
        </xsl:element>
    </xsl:if>
    </xsl:template>

    <xsl:template match="Coordinate"/>

</xsl:stylesheet>

Я надеялся, что тест "если" сможет гарантировать, что он только скопирует атрибуты Coordinate в Parent, но я получаю пустой вывод, когда я пытаюсь выполнить его здесь.

Подводя итог, если у узла есть дочерний элемент с именем "Coordinate", все в этом узле и его атрибуты должны быть перемещены в его Parent, а затем должен быть удален узел "Coordinate".

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Просто для удовольствия, эта таблица стилей с небольшой модификацией правила идентификации и другим пустым правилом для отбрасывания Coordinate элементов:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|Coordinate/@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Coordinate"/>
</xsl:stylesheet>

Вывод:

<Blocks>
  <Block ID="OA00" Name="Generic">
    <Design ID="DA00"/>
  </Block>
  <Block ID="OA01" Name="WildStar" DenyChange="true" X="50" Y="60">
    <Design ID="DA00"/>    
  </Block>
  <Block ID="OA02" Name="Eraser"/>
</Blocks>
1 голос
/ 04 апреля 2019

Все, что вам нужно, это шаблон, который соответствует любому элементу, у которого Coordinate в качестве дочернего элемента ...

<xsl:template match="*[Coordinate]">

Затем вы можете просто скопировать этот элемент и добавить атрибуты координат.

Попробуйте это XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*" />

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

    <xsl:template match="*[Coordinate]">
        <xsl:copy>
            <xsl:copy-of select="@*|Coordinate/@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Coordinate"/>
</xsl:stylesheet>

Обратите внимание, что в исходном XSLT у вас есть два шаблона, совпадающих с одним и тем же (в данном случае * 1010), что будет считаться ошибкой. Процессоры могут либо пометить ошибку, либо выбрать последние подходящие шаблоны

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