0

Certain xml specifications require a markup declaration to perform a task. One such example is below; a conditional to check a framework version in Wix

    <Condition Message="This application requires .NET Framework 4.6.2. Please install the .NET Framework then run this installer again.">
          <![CDATA[Installed OR WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED]]>
    </Condition>

While the condition is trivial to build an element for:

   def add_net462_prerequisite(self, parent):
        condition = ET.SubElement(
            parent,
            "Condition",
            Message="This application requires .NET Framework 4.6.2. "
                    "Please install the .NET Framework then run this installer again.",
        )

I can't seem to find a way to add a "markup declaration" to specify the line

<![CDATA[Installed OR WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED]]>

I've gone through the documentation of xml.etree.ElementTree and can't find anything about markup declarations; nor have I found anything via searching the web on markup declarations in that library or lxml's elementree.

A way to add raw text, a markup declaration, or another hack would be acceptable. I'm half considering re-reading the output file, locating the appropriate node and then adding the text programmatically, but I'm hoping it doesn't come to that.

Thank you for any assistance

Note: We're currently using wix 3.14; though this question is really regarding ElementTree.

EDIT: I've also attempted to use ElementTree.fromstring("<![CDATA[Installed OR WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED]]>"), which fails with a parse error.

Similarly, I've tried the below which, while it runs and builds an Element, that element fails to contain the <![CDATA[Installed OR WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED]]>

condition = ET.fromstring(
            '    <Condition Message="This application requires .NET Framework 4.6.2. '
            'Please install the .NET Framework then run this installer again.">'
            '        <![CDATA[Installed OR WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED]]>'
            '    </Condition>'
        )

Additional EDIT: It would seem that someone has posted a similar question before that I've finally located (and attempted to mark this as a duplicate of)

0

2 Answers 2

0

Many don't like this, but I prefer building elements "by hand", so I would propose the answer below.

Note that it requires lxml, not ElementTree, if available:

Assuming your xml looks like this:

cond = """
<root>
 <Conditions>
   <Condition Message="no message">This is a condition; another one is next
    <![CDATA[some random string]]>
   </Condition>
 </Conditions>
</root>"

Try this:

from lxml import etree
parser = etree.XMLParser(strip_cdata=False)
doc = etree.XML(cond, parser)
#the 2nd parameter above is key
n_cond = """<Condition Message="This application requires .NET Framework 4.6.2. Please install the .NET Framework then run this installer again.">
          <![CDATA[Installed OR WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED]]>
    </Condition>"""

destination = doc.xpath('.//Conditions')[0]
final = etree.fromstring(n_cond,parser)
#again, note the 2nd parameter above
destination.append(final)
etree.indent(doc, space='  ', level=0)
#above requires python 3.9 or above
print(etree.tostring(doc).decode())

Output:

<root>
  <Conditions>
    <Condition Message="no message">This is a condition; another one is next
    <![CDATA[some random string]]>
   </Condition>
    <Condition Message="This application requires .NET Framework 4.6.2. Please install the .NET Framework then run this installer again.">
          <![CDATA[Installed OR WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED]]>
    </Condition>
  </Conditions>
</root>
Sign up to request clarification or add additional context in comments.

Comments

0

Nothing in that condition needs to be escaped, so you can specify it as normal inner text.

2 Comments

Do you mind expanding on this answer? There is not "inner text" method in ElementTree, and the text and tail methods are both Elements, which would mean I have the same issue since this string does not conform to an Element's requirements (e.g. a tag, a special <! and similar)
text is a string and you don't need the CDATA because the inner text doesn't need to be escaped.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.