Вставьте узел XML в определенном положении существующего документа

Есть один способ, надеюсь, я правильно понял вопрос,

MockMvcRequestBuilders
.post("/servlet/api/update")
.content("{\"id\":1,\"toggle\":true}]")
.session(httpSession)
.contentType(MediaType.APPLICATION_JSON)
.andExpect(jsonPath("$[0].key",is("value")));

и Expect (jsonPath ("$ [0] .key", is ("value")))

вы можете использовать это для каждой клавиши и значения.

Или

попробуйте это,

 MockMvcRequestBuilders
.post("/servlet/api/update")
.content("{\"id\":1,\"toggle\":true}]")
.session(httpSession)
.contentType(MediaType.APPLICATION_JSON)
.andExpect(content().string(containsString("value")));
10
задан MyKey_ 14 May 2009 в 12:05
поделиться

3 ответа

[Заменил мой последний ответ. Теперь я лучше понимаю, что вам нужно.]

Вот решение XSLT 2.0:

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

  <xsl:template match="/root">
    <xsl:variable name="elements-after" select="t|u|v|w|x|y|z"/>
    <xsl:copy>
      <xsl:copy-of select="* except $elements-after"/>
      <s>new node</s>
      <xsl:copy-of select="$elements-after"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Вы должны явно указать либо элементы, которые идут после, либо элементы, которые идут до. (Необязательно перечислять оба.) Я бы предпочел выбрать более короткий из двух списков (отсюда «t» - «z» в приведенном выше примере вместо «a» - «r»).

ДОПОЛНИТЕЛЬНОЕ УЛУЧШЕНИЕ:

Это выполняет свою работу, но теперь вам нужно поддерживать список имен элементов в двух разных местах (в XSLT и в схеме). Если он сильно изменится, они могут рассинхронизироваться. Если вы добавите новый элемент в схему, но забудете добавить его в XSLT, он не будет скопирован. Если вас это беспокоит, вы можете реализовать свой собственный вид понимания схемы. Позволять' s скажем, ваша схема выглядит так:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="a" type="xs:string"/>
        <xs:element name="r" type="xs:string"/>
        <xs:element name="s" type="xs:string"/>
        <xs:element name="t" type="xs:string"/>
        <xs:element name="z" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

Теперь все, что вам нужно сделать, это изменить определение переменной $ elements-after:

  <xsl:variable name="elements-after" as="element()*">
    <xsl:variable name="root-decl" select="document('root.xsd')/*/xs:element[@name eq 'root']"/>
    <xsl:variable name="child-decls" select="$root-decl/xs:complexType/xs:sequence/xs:element"/>
    <xsl:variable name="decls-after" select="$child-decls[preceding-sibling::xs:element[@name eq 's']]"/>
    <xsl:sequence select="*[local-name() = $decls-after/@name]"/>
  </xsl:variable>

Это, очевидно, более сложно, но теперь вам не нужно перечислять какие-либо элементы ( кроме "s") в вашем коде. Поведение скрипта будет автоматически обновляться всякий раз, когда вы меняете схему (в частности, если вы добавляете новые элементы). Будет ли это излишеством или нет, зависит от вашего проекта. Я предлагаю это просто как дополнительное дополнение. : -)

если вам нужно было добавить новые элементы). Будет ли это излишеством или нет, зависит от вашего проекта. Я предлагаю это просто как дополнительное дополнение. : -)

если вам нужно было добавить новые элементы). Будет ли это излишеством или нет, зависит от вашего проекта. Я предлагаю это просто как дополнительное дополнение. : -)

19
ответ дан 3 December 2019 в 20:06
поделиться

Решение XPath:

/root/(.|a|r)[position()=last()]

Вы должны явно включить все узлы, вплоть до того, который вам нужен, так что вам понадобится другое выражение XPath для каждого узла, который вы хотите вставить после. Например, чтобы разместить его сразу после (если он существует):

/root/(.|a|r|t)[position()=last()]

Обратите внимание на особый случай, когда ни один из предыдущих узлов не присутствует: он возвращает ("."). Вам нужно будет это проверить и вставить новый узел в качестве первого дочернего элемента root, а не после него (обычный случай). Это не так уж и плохо: вам все равно придется как-то справиться с этим частным случаем. Другой способ справиться с этим особым случаем - следующий, который возвращает 0 узлов, если нет предшествующих узлов.

/root/(.|a|r|t)[position()=last() and position()!=1]

Проблема: можете ли вы найти лучший способ справиться с этим особым случаем?

0
ответ дан 3 December 2019 в 20:06
поделиться

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

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

Как только я увижу узел> r ( t , u , ..., ] z ) или конечный тег корневого узла, я бы написал узел s , если sWasWritten не был истинным и установил флаг sWasWritten .

0
ответ дан 3 December 2019 в 20:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: