Ошибка преобразования Java XML и XSLT: пространство имен для префикса 'm' не объявлено - PullRequest
0 голосов
/ 15 сентября 2018

Я пытаюсь преобразовать документ XML с помощью javax.xml.transform.Transformer и XSLT, и у меня возникли проблемы с префиксом пространства имен, который не распознается при вызове метода преобразования.

Вот документ XML, для которого определен префикс пространства имен «m»:

<?xml version="1.0" encoding="UTF-8"?>
<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0">
  <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="1.0">
    <Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" Namespace="SITUATION">
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

Вот XSL, который в настоящее время просто копирует весь XML-документ (позже я хотел бы расширить его для объединения в другой XML-документ, аналогично тому, что описано здесь: https://stackoverflow.com/a/5706319/208011):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- Copy everything including attributes as default action -->
    <xsl:template match="*">
        <xsl:element name="{name()}">
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

Вот код Java:

Source xsltSource = new StreamSource(new File(getClass().getClassLoader().getResource("merge-metadata.xsl").getFile()));
transformer = transFact.newTransformer(xsltSource);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document input = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(s1)));
StringWriter out = new StringWriter();
transformer.transform(new DOMSource(input), new StreamResult(out));

Вот трассировка стека:

Caused by: java.lang.RuntimeException: Namespace for prefix 'm' has not been declared.
    at com.sun.org.apache.xml.internal.serializer.SerializerBase.getNamespaceURI(SerializerBase.java:915)
    at com.sun.org.apache.xml.internal.serializer.SerializerBase.addAttribute(SerializerBase.java:431)
    at com.sun.org.apache.xml.internal.serializer.ToUnknownStream.addAttribute(ToUnknownStream.java:316)

В конце концов я хочу объединить этот XML-документ с другим, но я не могу обойти проблему с пространством имен, чтобы просто скопировать этот.

Если я не использую таблицу стилей xsl в методе фабрики преобразователей newTransformer (), я не получаю ошибку пространства имен, и результат преобразования точно такой же, как и в исходном XML-документе.

Если я укажу DocumentBuilderFactory, чтобы она не поддерживала пространство имен, я не получу исключение, но в результате преобразования отсутствуют пространства имен.

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 15 сентября 2018

Ваше созданное вручную преобразование псевдоидентификации теряет объявления пространства имен и завершается неудачно, когда оно пытается назвать элемент с необъявленным префиксом пространства имен:

<xsl:element name="{name()}">

Вместо этого используйте стандартное преобразование идентичности:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...