# XML


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

``` python
from IPython.display import Markdown
from pprint import pprint

from fastcore.test import test_eq, test_ne
```

## FT functions

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L31"
target="_blank" style="float:right; font-size:smaller">source</a>

### attrmap

``` python

def attrmap(
    o
):

```

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L38"
target="_blank" style="float:right; font-size:smaller">source</a>

### valmap

``` python

def valmap(
    o
):

```

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L59"
target="_blank" style="float:right; font-size:smaller">source</a>

### FT

``` python

def FT(
    tag:str, cs:tuple, attrs:dict=None, void_:bool=False, kwargs:VAR_KEYWORD
):

```

*A ‘Fast Tag’ structure, containing `tag`,`children`,and `attrs`*

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L108"
target="_blank" style="float:right; font-size:smaller">source</a>

### ft

``` python

def ft(
    tag:str, c:VAR_POSITIONAL, void_:bool=False, attrmap:callable=attrmap, valmap:callable=valmap, ft_cls:type=FT,
    kw:VAR_KEYWORD
):

```

*Create an [`FT`](https://fastcore.fast.ai/xml.html#ft) structure for
[`to_xml()`](https://fastcore.fast.ai/xml.html#to_xml)*

The main HTML tags are exported as
[`ft`](https://fastcore.fast.ai/xml.html#ft) partials.

Attributes are passed as keywords. Use ‘klass’ and ‘fr’ instead of
‘class’ and ‘for’, to avoid Python reserved word clashes.

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L128"
target="_blank" style="float:right; font-size:smaller">source</a>

### Html

``` python

def Html(
    c:VAR_POSITIONAL, doctype:bool=True, kwargs:VAR_KEYWORD
)->FT:

```

*An HTML tag, optionally preceeded by `!DOCTYPE HTML`*

``` python
samp = Html(
    Head(Title('Some page')),
    Body(Div('Some text\nanother line', (Input(name="jph's"), Img(src="filename", data=1)),
             cls=['myclass', 'another'],
             style={'padding':1, 'margin':2}))
)
pprint(samp)
```

    (!doctype((),{'html': True}),
     html((head((title(('Some page',),{}),),{}), body((div(('Some text\nanother line', input((),{'name': "jph's"}), img((),{'src': 'filename', 'data': 1})),{'class': 'myclass another', 'style': 'padding:1; margin:2'}),),{})),{}))

``` python
elem = P('Some text', id="myid")
print(elem.tag)
print(elem.children)
print(elem.attrs)
```

    p
    ('Some text',)
    {'id': 'myid'}

You can get and set attrs directly:

``` python
elem.id = 'newid'
print(elem.id, elem.get('id'), elem.get('foo', 'missing'))
elem
```

    newid newid missing

    p(('Some text',),{'id': 'newid'})

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L135"
target="_blank" style="float:right; font-size:smaller">source</a>

### Safe

``` python

def Safe(
    args:VAR_POSITIONAL, kwargs:VAR_KEYWORD
):

```

*str(object=’’) -\> str* str(bytes_or_buffer\[, encoding\[, errors\]\])
-\> str

Create a new string object from the given object. If encoding or errors
is specified, then the object must expose a data buffer that will be
decoded using the given encoding and error handler. Otherwise, returns
the result of object.\_\_str\_\_() (if defined) or repr(object).
encoding defaults to sys.getdefaultencoding(). errors defaults to
‘strict’.

## Conversion to XML/HTML

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L211"
target="_blank" style="float:right; font-size:smaller">source</a>

### to_xml

``` python

def to_xml(
    elms:VAR_POSITIONAL, lvl:int=0, indent:bool=True, do_escape:bool=True
):

```

*Convert [`ft`](https://fastcore.fast.ai/xml.html#ft) element tree into
an XML string*

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L222"
target="_blank" style="float:right; font-size:smaller">source</a>

### FT.\_\_html\_\_

``` python

def __html__(
    
):

```

``` python
test_eq(to_xml(B('Bold Text'), Div(P('Paragraph Text'))),
    '<b>Bold Text</b>\n<div>\n  <p>Paragraph Text</p>\n</div>\n')
```

``` python
to_xml(Div("<script>alert('XSS')</script>"), do_escape=True)
```

    "<div>&lt;script&gt;alert('XSS')&lt;/script&gt;</div>\n"

``` python
h = to_xml(samp, do_escape=False)
print(h)
```

    <!doctype html>
    <html>
      <head>
        <title>Some page</title>
      </head>
      <body>
        <div class="myclass another" style="padding:1; margin:2">
    Some text
    another line      <input name="jph's">
    <img src="filename" data="1">    </div>
      </body>
    </html>

``` python
c = I('hello')
print(c)
```

    <i>hello</i>

``` python
c
```

<i>hello</i>

``` python
class PageTitle:
    def __ft__(self): return H1("Hello")

class HomePage:
    def __ft__(self): return Div(PageTitle(), Div('hello'))

h = to_xml(Div(HomePage()))
expected_output = """<div>
  <div>
    <h1>Hello</h1>
    <div>hello</div>
  </div>
</div>
"""
assert h == expected_output
```

``` python
print(h)
```

    <div>
      <div>
        <h1>Hello</h1>
        <div>hello</div>
      </div>
    </div>

``` python
h = to_xml(samp, indent=False)
print(h)
```

    <!doctype html><html><head><title>Some page</title></head><body><div class="myclass another" style="padding:1; margin:2">Some text
    another line<input name="jph's"><img src="filename" data="1"></div></body></html>

Interoperability both directions with Django and Jinja using the
[**html**()
protocol](https://jinja.palletsprojects.com/en/3.1.x/templates/#jinja-filters.escape):

``` python
def _esc(s): return s.__html__() if hasattr(s, '__html__') else Safe(escape(s))

r = Safe('<b>Hello from Django</b>')
print(to_xml(Div(r)))
print(_esc(Div(P('Hello from fastcore <3'))))
```

    <div><b>Hello from Django</b></div>

    <div><p>Hello from fastcore &lt;3</p></div>

FT attributes are rendered with
[`to_xml`](https://fastcore.fast.ai/xml.html#to_xml):

``` python
print(to_xml(P('hi', value=Div('ho'))))
```

    <p value="<div>ho</div>">hi</p>

FT components also stringify with
[`to_xml`](https://fastcore.fast.ai/xml.html#to_xml):

``` python
print(Div('ho'))
```

    <div>ho</div>

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L236"
target="_blank" style="float:right; font-size:smaller">source</a>

### FT.\_\_hash\_\_

``` python

def __hash__(
    
):

```

*Return hash(self).*

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L231"
target="_blank" style="float:right; font-size:smaller">source</a>

### FT.\_\_eq\_\_

``` python

def __eq__(
    other
):

```

*Return self==value.*

[`FT`](https://fastcore.fast.ai/xml.html#ft) object equality and hashing
is based on tag, attrs, and children.

``` python
test_eq(Div('hello', id='x'), Div('hello', id='x'))
test_ne(Div('hello'), Div('goodbye'))
test_ne(Div('hello', id='a'), Div('hello', id='b'))
test_ne(P('hello'), Div('hello'))

test_eq(hash(Div('hello', id='x')), hash(Div('hello', id='x')))
assert hash(Div('hello')), hash(Div('goodbye'))
```

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L239"
target="_blank" style="float:right; font-size:smaller">source</a>

### dict2xml

``` python

def dict2xml(
    d, do_escape:bool=False, unwrap:NoneType=None
):

```

*Convert `d` to XML tags, one per key/value pair, unwrapping if only
single key in `unwrap` exists*

[`dict2xml`](https://fastcore.fast.ai/xml.html#dict2xml) takes a Python
dictionary and converts each key-value pair into an XML element where
the key becomes the tag name and the value becomes its text content. All
elements are concatenated via
[`to_xml`](https://fastcore.fast.ai/xml.html#to_xml):

``` python
d = {'name': 'Jeremy', 'lang': 'Python'}
print(dict2xml(d))
```

    <name>Jeremy</name>
    <lang>Python</lang>

If there’s only one key, it is returned if it matches anything in
`unwrap`:

``` python
d = {'name': 'Jeremy'}
print(dict2xml(d, unwrap='name'))
```

    Jeremy

## Display

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L246"
target="_blank" style="float:right; font-size:smaller">source</a>

### highlight

``` python

def highlight(
    s, lang:str='html'
):

```

*Markdown to syntax-highlight `s` in language `lang`*

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L251"
target="_blank" style="float:right; font-size:smaller">source</a>

### showtags

``` python

def showtags(
    s
):

```

You can also reorder the children to come *after* the attrs, if you use
this alternative syntax for [`FT`](https://fastcore.fast.ai/xml.html#ft)
where the children are in a second pair of `()` (behind the scenes this
is because [`FT`](https://fastcore.fast.ai/xml.html#ft) implements
`__call__` to add children).

``` python
hl_md(
Body(klass='myclass')(
    Div(style='padding:3px')(
        'Some text 1<2',
        I(spurious=True)('in italics'),
        Input(name='me'),
        Img(src="filename", data=1)
    )
))
```

<div class="prose">

``` html
<body class="myclass"><div style="padding:3px">Some text 1&lt;2<i spurious>in italics</i><input name="me"><img src="filename" data="1"></div></body>
```

</div>

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/xml.py#L259"
target="_blank" style="float:right; font-size:smaller">source</a>

### **getattr**

``` python

def __getattr__(
    tag
):

```
